【LeetCode-中等题】200. 岛屿数量

文章目录

    • 题目
    • 方法一:深度优先搜索 dfs
    • 方法二:广度优先搜索 bfs
    • 方法三:(重点掌握)并查集

题目

在这里插入图片描述

方法一:深度优先搜索 dfs

思路:让一个扫描指针扫描每一个格子,然后每扫到一个为1的格子,道与数量count+1,,并且对这个格子进行dfs(四个方向dfs)将此次格子的dfs周边的格子全部置为0,接着指针继续扫描下一个为1的格子,重复上面的动作。
在这里插入图片描述

扫描整个二维网格。如果一个位置为 1,则以其为起始节点开始进行深度优先搜索。在深度优先搜索的过程中,每个搜索到的 1 都会被重新标记为 0。
最终岛屿的数量就是我们进行深度优先搜索的次数。

图的dfs遍历框架思路:岛屿类问题的通用解法、DFS 遍历框架

//方法一 深度优先搜索 dfsint row = 0; //网格行数 全局变量int col = 0; //网格列数 全局变量public int numIslands(char[][] grid) {if(grid[0].length==0) return 0;this.row = grid.length;//给行列全局变量赋值this.col = grid[0].length;int count = 0;//岛屿计数for(int r = 0;r<row ;r++)//遍历网格每一个各格子for(int c = 0;c<col ;c++){if(grid[r][c]=='1'){//如果网格数字为1,说明存在岛屿  count++;dfs(grid,r,c);//对该格子进行dfs  将这个格子旁边的1统统置为0}}return count;}// dfspublic void dfs(char[][] grid ,int r,int c){if(r>=row || c>=col || r<0 || c<0 || grid[r][c]=='0'){ //递归终止条件return;}grid[r][c] ='0';// 将1全部置为0 //对四个方向进行递归dfs(grid,r-1,c);dfs(grid,r+1,c);dfs(grid,r,c+1);dfs(grid,r,c-1);}

方法二:广度优先搜索 bfs

思路:
当遍历指针指向了一个1的网格,count++,就率先将该位置的绝对坐标(行*总列数+列)存入队列中,然后将该位置设置为0,接着进行while循环,从队列取出绝对位置,转换为x y坐标,然后根据x y 坐标 去判断当前位置的上下左右是否有1,是的话,就加入队列,并且置为0,直到循环结束(while循环做的事,就是在判断从对列拿出的位置周围四个方向是否有1,有就全部置为0,持续处理队列弹出的元素)

然后继续移动指针到下一个1的位置,继续前面的步骤

在这里插入图片描述
因为队列只能存一个整数,所以只能先存绝对位置,到时候弹出这个绝对位置的值,转换为行列就可以了
绝对位置:(举例 1,2 位置)
绝对位置 = 1*列数(3)+2 = 5
解析绝对位置:
行: 5 /列数 (3)= 1
列: 5%列数(3)= 2

在这里插入图片描述

扫描整个二维网格。如果一个位置为 1,则以其为起始节点开始进行深度优先搜索。在深度优先搜索的过程中,每个搜索到的 1 都会被重新标记为 0。
最终岛屿的数量就是我们进行深度优先搜索的次数。

// 方法二 广度优先搜索 bfs int row = 0; //网格行数 全局变量int col = 0; //网格列数 全局变量public int numIslands(char[][] grid) {if(grid == null||grid[0].length==0) return 0;this.row = grid.length;//给行列全局变量赋值this.col = grid[0].length;int count = 0;Queue<Integer> queue = new LinkedList<>();for(int r = 0 ; r<row ; r++)for(int c = 0 ; c<col ; c++){if(grid[r][c]=='1'){// 说明有岛屿count++;//将当前位置的x和y坐标入队  直接存入整数绝对位置queue.offer(r*col+c);  //第r行  第c列grid[r][c]='0';//然后置为0while(!queue.isEmpty()){//如果队列不为空 说明其中有包含1 的元素int mid = queue.poll();  //取出该元素的绝对坐标//将该元素绝对坐标转换为  对应的x 和 y坐标int x = mid / col;//行int y = mid % col;//列//对该元素四个方向判断是否有1,是就将对应绝对坐标加入到队列,并且将该位置置为0//上if(y-1 >=0 && grid[x][y-1]=='1'){queue.offer(x*col +y-1);grid[x][y-1]='0';}//下if(y+1 < col && grid[x][y+1]=='1'){queue.offer(x*col +y+1);grid[x][y+1]='0';}//左if(x-1 >=0 && grid[x-1][y]=='1'){queue.offer((x-1)*col +y);grid[x-1][y]='0';}//右if(x+1 <row && grid[x+1][y]=='1'){queue.offer((x+1)*col +y);grid[x+1][y]='0';}}}}return count;}

方法三:(重点掌握)并查集

方法三 并查集 关键在于find方法找祖先 然后union方法同化不是相同祖先的两个临近格子(只需要比较下 和右两个方向) 以及将二维数组,以行坐标*列数+列坐标 = 祖先 的方式转为一维数组 方便进行找祖先 同化祖先,

岛屿数 = 1的个数-同化次数

这题的对比方向可以只是 往右和往下对比就足够了,无需往上,往左 (往上往左都是重复动作)

在这里插入图片描述
在这里插入图片描述

 int[] p = null;//祖先数组  初始化 自己初始化祖先就是自己  长度为格子总数int res = 0 ;public int numIslands(char[][] grid) {int m = grid.length;int n = grid[0].length;p = new int[m*n];//初始化 parent 数组,记录初始岛屿数(也就是 1 的数目)for (int i = 0; i < m; i++)for(int j = 0; j < n; j++){if(grid[i][j]=='1') res++;int idx = i*n + j;p[idx] = idx;}for (int i = 0; i < m; i++)for(int j = 0; j < n; j++){int idx = i * n + j;if(grid[i][j] == '1'){//向下合并if (i+1 < m && grid[i+1][j] == '1') { //合并岛屿union(idx, (i + 1) * n + j);}//向右合并if (j+1 <n && grid[i][j+1] == '1') {union(idx, i * n + j + 1);}}}return res;}// 递归找祖先int find(int i){if (p[i] == i) return p[i];return p[i] = find(p[i]);}void union(int i, int j){if (find(i) == find(j)) return; //若祖先相同  则不做union操作  p[find(j)] = p[find(i)];//若祖先不同  ,说明之前没有同化过,则进行同化(修改被比较位置的祖先为当前待比较位置的祖先)res--;//同化一次,res(1的总数) -1}

以上三种方法这个B站的小姐姐讲的非常透彻
岛屿数量 Number of Islands—作者: 爱学习的饲养员

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/94519.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Spring Boot日志基础使用 设置日志级别

然后 我们来说日志 日志在实际开发中还是非常重要的 即可记录项目状态和一些特殊情况发生 因为 我们这里不是将项目 所以 讲的也不会特别深 基本还是将Spring Boot的日志设置或控制这一类的东西 相对业务的领域我们就不涉及了 日志 log 初期最明显的作用在于 开发中 你可以用…

element+vue table表格全部数据和已选数据联动

1.组件TableChoose <template><div class"tableChooseBox"><div class"tableRow"><div class"tableCard"><div class"tableHeadTip">全部{{ labelTitle }}</div><slot name"body" …

OpenCV(十三):图像中绘制直线、圆形、椭圆形、矩形、多边形和文字

目录 1.绘制直线line() 2.绘制圆形circle() 3.绘制椭圆形ellipse() 4.绘制矩形rectangle() 5.绘制多边形 fillPoly() 6.绘制文字putText() 7.例子 1.绘制直线line() CV_EXPORTS_W void line(InputOutputArray img,Point pt1, Point pt2,const Scalar& color,int t…

无涯教程-Android Studio函数

第1步-系统要求 您将很高兴知道您可以在以下两种操作系统之一上开始Android应用程序的开发- MicrosoftWindows10/8/7/Vista/2003(32或64位)MacOSX10.8.5或更高版本,最高10.9(小牛) GNOME或KDE桌面 第二点是,开发Android应用程序所需的所有工具都是开源的,可以从Web上下载。以…

vue的第2篇 第一个vue程序

一 环境的搭建 1.1常见前端开发ide 1.2 安装vs.code 1.下载地址&#xff1a;Visual Studio Code - Code Editing. Redefined 2.进行安装 1.2.1 vscode的中文插件安装 1.在搜索框输入“chinese” 2.安装完成重启&#xff0c;如下变成中文 1.2.2 修改工作区的颜色 选中[浅色]…

编译KArchive在windows10下

使用QT6和VS2019编译KArchive的简要步骤&#xff1a; 安装 Qt &#xff0c;我是用源码自己编译的 "F:\qtbuild"安装CMakefile并配置环境变量安装Git下载ECM源码 https://github.com/KDE/extra-cmake-modules.git-------------------------------------------------…

SpringBoot Mybatis 多数据源 MySQL+Oracle

一、背景 在SpringBoot Mybatis 项目中&#xff0c;需要连接 多个数据源&#xff0c;连接多个数据库&#xff0c;需要连接一个MySQL数据库和一个Oracle数据库 二、依赖 pom.xml <dependencies><dependency><groupId>org.springframework.boot</groupId&…

上半年净利润同比改善22.18%,赛力斯的韧性从何而来?

2023年上半年&#xff0c;伴随特斯拉一声全球大降价&#xff0c;新能源汽车行业价格混战拉开帷幕&#xff0c;车企业绩纷纷承压。“卷”风盛行之下&#xff0c;谁抗住了压力&#xff1f; 8月30日&#xff0c;赛力斯发布了中期业绩报告。根据财报&#xff0c;2023年上半年&…

kotlin实现猜数游戏

游戏规则 1.程序随机生成一个1到100的数字&#xff0c;作为MagicNumber 2.用户根据提示输入数据&#xff0c;只有三次机会输入数据 代码 代码很简单&#xff0c;使用了let内置函数 fun main() {//生成随机数可以使用java的方法//val magicNumber Random().nextInt(11)val ma…

Tensorflow调用训练好的yolov5模型进行推理

文章目录 1、安装TensorFlow-GPU版本1.2、验证是否安装正常 2、将训练好的pt文件转换成onnx文件2.2、什么是Onnx模型和Tensorflow模型2.1、将onnx文件转换成pb文件 1、安装TensorFlow-GPU版本 1、创建虚拟环境python3.8 conda create -n TF2.4 python3.82、进入虚拟环境 conda…

MySQL中日期、时间直接相减的坑

前言 在牛客网上写一道 SQL 题时&#xff0c;需要计算两个日期之间相隔的秒数&#xff0c;我在写的时候直接将两个日期进行相减&#xff0c;得出来的值却不是相差的秒数。 情景再现 我在 MySQL 中进行了测试&#xff0c;得出的结论是&#xff1a;如果日期类型直接相减&#…

ElasticSearch学习4--复杂查询

1、查询分类 查询所有&#xff1a;查询出所有数据&#xff0c;一般测试用。例如&#xff1a;match_all全文检索&#xff08;full text&#xff09;查询&#xff1a;利用分词器对用户输入内容分词&#xff0c;然后去倒排索引库中匹配。例如&#xff1a; match_query 根据单个字段…