热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

Leetcode200查找岛屿数量详解

Leetcode20

 往期博客:

Leetcode1-两数之和详解

Leetcode2-两数相加代码详解

Leetcode20-有效的括号详解

Leetcode21-合并两个有序链表详解

Leetcode22-有效括号生成详解

Leetcode24-两两交换链表中的节点详解

Leetcode27-移除元素详解

Leetcode46-全排列详解

Leetcode49-字母异位分组详解

Leetcode53-最大子数组和详解

Leetcode56-合并区间详解

LeetCode57-插入区间详解

Leetcode77-组合详解

Leetcode78-子集详解

Leetcode90-子集II详解

Leetcode94-二叉树的中序遍历详解

Leetcode102-二叉树的层序遍历详解

Leetcode107-二叉树的层序遍历II详解

Leetcode169-多数元素详解


目录

题目

示例

解析

DFS

BFS

代码

DFS

BFS


题目

给你一个由 '1'(陆地)和 '0'(水)组成的的二维网格,请你计算网格中岛屿的数量。

岛屿总是被水包围,并且每座岛屿只能由水平方向和/或竖直方向上相邻的陆地连接形成。

此外,你可以假设该网格的四条边均被水包围。

分析:

1. 数字1的部分为大陆,数字0的部分为岛屿

2. 大陆只能与上下左右的1组成,斜对角方向的1不能组成


示例

示例1

输入:grid = [
  ["1","1","1","1","0"],
  ["1","1","0","1","0"],
  ["1","1","0","0","0"],
  ["0","0","0","0","0"]
]
输出:1

示例2

输入:grid = [
  ["1","1","0","0","0"],
  ["1","1","0","0","0"],
  ["0","0","1","0","0"],
  ["0","0","0","1","1"]
]
输出:3


解析

DFS

对于示例2,首先根据规则可以看到,总共有三个岛屿

使用DFS方法的思想进行分析,首先第一步可以设置一个指针,指针初始指向(0,0)的位置,由于只能上下左右的1能构成岛屿,所以第二步将(0,0)位置上下左右的1变成0,证明这些1已经与(0,0)位置构成了岛屿,然后第三步再将指针指向(0,1)位置移动,第四步同样将上下左右的1变成0,然后再移动,直到当前位置的上下左右全部为0没有1时,说明当前岛屿已经结束,再继续移动找下一个岛屿,直到到达整个二维数组的最后。

根据示例2详细分析

 当指针继续移动到(0,2)的位置时,此位置的上下左右全部为0,说明没有符合的1能继续组成岛屿,所以此时岛屿1已经全部找到。

继续移动指针,去找下一个岛屿......

当指针移动到(2,2)的位置时,出现了1,说明又有新的岛屿出现了,同样进行1变0的操作,但是此时上下左右都是0,说明岛屿已经全部找到,这是一个“小岛屿”

同样继续移动指针,去找下一个岛屿......

当指针移动到(3,3)的位置时又出现了1,说明有新的岛屿出现,将上下左右的1变为0

当指针移动到最后时,所有区域都已经遍历完了

BFS

BFS方法的过程也是找上下左右的1的过程,不过这里要用到队列,大致过程为第一步将指针指向(0,0)的位置,第二步将该位置的坐标放入队列中,第三步从队列中取出坐标位置,第四步将坐标上下左右为1的位置放入队列中

 第五步将上下左右为1的位置变为0,第六步取出队列第一个元素,并将其上下左右为1的位置放入队列,第七步将为1的位置变成0

 依次取出队列中的坐标,并判断上下左右是否有1,直到队列中没有坐标

移动指针,直到移动到下一个为1 的位置,则找到第二个岛屿

 移动指针,找到第三个岛屿


代码

DFS

class Solution: def numIslands(self, grid: List[List[str]]) -> int: if grid is None or len(grid) == 0: # 如果整个区域为空,则无岛屿,直接返回0 return 0 result = 0 # 记录岛屿数量 row = len(grid) # 整个区域的行数 col = len(grid[0]) # 整个区域的列数 # 用2个for循环遍历整个区域 for i in range(0, row): for j in range(0, col): if grid[i][j] == '1': # 找到了新岛屿 result += 1 self.dfs(grid, i, j, row, col) return result def dfs(self, grid, x, y, row, col): # (x,y)为当前指针所指位置 # x,y在区域外时直接停止循环 if x<0 or y<0 or x>=row or y>= col or grid[x][y]=='0': return grid[x][y] = '0' #将1变0 # 找上下左右为1的位置变0 self.dfs(grid, x-1, y, row, col) # 左边变0 self.dfs(grid, x+1, y, row, col) # 右边变0 self.dfs(grid, x, y-1, row, col) # 上边变0 self.dfs(grid, x, y+1, row, col) # 下边变0

BFS

class Solution: def numIslands(self, grid: List[List[str]]) -> int: if grid is None or len(grid) == 0: # 如果整个区域为空,则无岛屿,直接返回0 return 0 result = 0 # 记录岛屿数量 row = len(grid) # 整个区域的行数 col = len(grid[0]) # 整个区域的列数 queue = [] for i in range(0, row): for j in range(0, col): if grid[i][j] == '1': result += 1 queue.append([i,j]) grid[i][j] = '0' while len(queue) > 0: cur = queue.pop() x = cur[0] y = cur[1] if x-1 >= 0 and grid[x-1][y] == '1': queue.append([x-1,y]) grid[x-1][y] = '0' if y-1 >= 0 and grid[x][y-1] == '1': queue.append([x,y-1]) grid[x][y-1] = '0' if x+1

推荐阅读
  • STL迭代器的种类及其功能介绍
    本文介绍了标准模板库(STL)定义的五种迭代器的种类和功能。通过图表展示了这几种迭代器之间的关系,并详细描述了各个迭代器的功能和使用方法。其中,输入迭代器用于从容器中读取元素,输出迭代器用于向容器中写入元素,正向迭代器是输入迭代器和输出迭代器的组合。本文的目的是帮助读者更好地理解STL迭代器的使用方法和特点。 ... [详细]
  • 深入解析Linux下的I/O多路转接epoll技术
    本文深入解析了Linux下的I/O多路转接epoll技术,介绍了select和poll函数的问题,以及epoll函数的设计和优点。同时讲解了epoll函数的使用方法,包括epoll_create和epoll_ctl两个系统调用。 ... [详细]
  • LeetCode笔记:剑指Offer 41. 数据流中的中位数(Java、堆、优先队列、知识点)
    本文介绍了LeetCode剑指Offer 41题的解题思路和代码实现,主要涉及了Java中的优先队列和堆排序的知识点。优先队列是Queue接口的实现,可以对其中的元素进行排序,采用小顶堆的方式进行排序。本文还介绍了Java中queue的offer、poll、add、remove、element、peek等方法的区别和用法。 ... [详细]
  • 深入理解Kafka服务端请求队列中请求的处理
    本文深入分析了Kafka服务端请求队列中请求的处理过程,详细介绍了请求的封装和放入请求队列的过程,以及处理请求的线程池的创建和容量设置。通过场景分析、图示说明和源码分析,帮助读者更好地理解Kafka服务端的工作原理。 ... [详细]
  • 本文分享了一个关于在C#中使用异步代码的问题,作者在控制台中运行时代码正常工作,但在Windows窗体中却无法正常工作。作者尝试搜索局域网上的主机,但在窗体中计数器没有减少。文章提供了相关的代码和解决思路。 ... [详细]
  • Java容器中的compareto方法排序原理解析
    本文从源码解析Java容器中的compareto方法的排序原理,讲解了在使用数组存储数据时的限制以及存储效率的问题。同时提到了Redis的五大数据结构和list、set等知识点,回忆了作者大学时代的Java学习经历。文章以作者做的思维导图作为目录,展示了整个讲解过程。 ... [详细]
  • 本文详细介绍了Linux中进程控制块PCBtask_struct结构体的结构和作用,包括进程状态、进程号、待处理信号、进程地址空间、调度标志、锁深度、基本时间片、调度策略以及内存管理信息等方面的内容。阅读本文可以更加深入地了解Linux进程管理的原理和机制。 ... [详细]
  • 不同优化算法的比较分析及实验验证
    本文介绍了神经网络优化中常用的优化方法,包括学习率调整和梯度估计修正,并通过实验验证了不同优化算法的效果。实验结果表明,Adam算法在综合考虑学习率调整和梯度估计修正方面表现较好。该研究对于优化神经网络的训练过程具有指导意义。 ... [详细]
  • Python瓦片图下载、合并、绘图、标记的代码示例
    本文提供了Python瓦片图下载、合并、绘图、标记的代码示例,包括下载代码、多线程下载、图像处理等功能。通过参考geoserver,使用PIL、cv2、numpy、gdal、osr等库实现了瓦片图的下载、合并、绘图和标记功能。代码示例详细介绍了各个功能的实现方法,供读者参考使用。 ... [详细]
  • 本文介绍了Python爬虫技术基础篇面向对象高级编程(中)中的多重继承概念。通过继承,子类可以扩展父类的功能。文章以动物类层次的设计为例,讨论了按照不同分类方式设计类层次的复杂性和多重继承的优势。最后给出了哺乳动物和鸟类的设计示例,以及能跑、能飞、宠物类和非宠物类的增加对类数量的影响。 ... [详细]
  • IjustinheritedsomewebpageswhichusesMooTools.IneverusedMooTools.NowIneedtoaddsomef ... [详细]
  • 重入锁(ReentrantLock)学习及实现原理
    本文介绍了重入锁(ReentrantLock)的学习及实现原理。在学习synchronized的基础上,重入锁提供了更多的灵活性和功能。文章详细介绍了重入锁的特性、使用方法和实现原理,并提供了类图和测试代码供读者参考。重入锁支持重入和公平与非公平两种实现方式,通过对比和分析,读者可以更好地理解和应用重入锁。 ... [详细]
  • 带添加按钮的GridView,item的删除事件
    先上图片效果;gridView无数据时显示添加按钮,有数据时,第一格显示添加按钮,后面显示数据:布局文件:addr_manage.xml<?xmlve ... [详细]
  • linux进阶50——无锁CAS
    1.概念比较并交换(compareandswap,CAS),是原⼦操作的⼀种,可⽤于在多线程编程中实现不被打断的数据交换操作࿰ ... [详细]
  • 本文介绍了Python字典视图对象的示例和用法。通过对示例代码的解释,展示了字典视图对象的基本操作和特点。字典视图对象可以通过迭代或转换为列表来获取字典的键或值。同时,字典视图对象也是动态的,可以反映字典的变化。通过学习字典视图对象的用法,可以更好地理解和处理字典数据。 ... [详细]
author-avatar
G眯眼猫2850927647Ona
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有