当前位置: 首页 > news >正文

【力扣100题】64.岛屿数量

题目描述

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

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

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

示例

示例 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

提示:

  • m == grid.length
  • n == grid[i].length
  • 1 <= m, n <= 300
  • grid[i][j] 的值为 ‘0’ 或 ‘1’

解题思路总览

方法核心思想时间复杂度空间复杂度备注
DFS(深度优先搜索)从每个未访问的陆地开始遍历O(m*n)O(m*n)推荐解法
BFS(广度优先搜索)用队列逐层扩展O(m*n)O(m*n)思路类似
并查集将陆地进行合并O(m*n * alpha)O(m*n)较复杂
迭代 DFS用栈模拟递归O(m*n)O(m*n)避免递归栈溢出

一、核心解法:DFS(深度优先搜索)

核心思想

遍历整个网格,遇到未访问的陆地 ‘1’ 时,就找到了一个新岛屿,然后从这个位置出发,深度优先搜索把所有相邻的陆地都标记为已访问。

核心步骤: 1. 遍历网格每个位置 2. 遇到未访问的 '1',岛屿数 +1 3. 从该位置出发 DFS,标记所有相连的 '1' 4. 继续遍历,重复上述过程

关键洞察

为什么 DFS 能解决问题? 因为岛屿的定义是:相邻(上下左右)的陆地连成的区域。 当我们找到一个未访问的陆地 '1' 时: - 它是一个新岛屿的起点 - 通过 DFS 可以找到所有和它相连的陆地 - 这些陆地都属于同一个岛屿 遍历完成后,所有陆地都被标记,岛屿数量就是答案。

图解

grid = [ ['1','1','1','1','0'], ['1','1','0','1','0'], ['1','1','0','0','0'], ['0','0','0','0','0'] ] 遍历过程: 初始: visited 全部为 false ans = 0 (i=0, j=0): grid[0][0]='1', 未访问 ans = 1 DFS(0,0): 标记 [0,0],[0,1],[0,2],[0,3],[1,0],[1,1],[1,2],[2,0],[2,1],[2,2] visited: 第一行全标记,第二行前两列标记,第三行前两列标记 (i=0, j=1-3): 已被访问,跳过 (i=0, j=4): '0',跳过 (i=1, j=0-4): 已被访问,跳过 (i=2, j=0-4): 已被访问,跳过 (i=3, j=0-4): 全为 '0',跳过 输出: ans = 1
grid = [ ['1','1','0','0','0'], ['1','1','0','0','0'], ['0','0','1','0','0'], ['0','0','0','1','1'] ] 遍历过程: 初始: visited 全部为 false ans = 0 (i=0, j=0): grid[0][0]='1', 未访问 ans = 1 DFS(0,0): 标记 [0,0],[0,1],[1,0],[1,1] visited: 左上角 2x2 区域 (i=0, j=2-4): '0' 或已访问,跳过 (i=1, j=2-4): 跳过 (i=2, j=0-1): '0',跳过 (i=2, j=2): grid[2][2]='1', 未访问 ans = 2 DFS(2,2): 标记 [2,2] (i=2, j=3-4): 已访问或 '0' (i=3, j=0-2): '0',跳过 (i=3, j=3): grid[3][3]='1', 未访问 ans = 3 DFS(3,3): 标记 [3,3],[3,4] visited: 右下角 2x2 区域 输出: ans = 3

二、算法流程图

输入: grid = [ ['1','1','1'], ['1','1','0'], ['0','0','1'] ] 初始化: visited = [[false,false,false], [false,false,false], [false,false,false]] ans = 0 dir = [[-1,0],[0,-1],[1,0],[0,1]] // 上左下右 遍历 (i=0, j=0): grid[0][0]='1', visited[0][0]=false ans = 1 DFS(0,0): visited[0][0]=true 尝试上: i=-1, 越界 尝试左: j=-1, 越界 尝试下: (1,0)='1', 未访问 -> DFS(1,0) visited[1][0]=true 上下左右探索 -> 递归到 (0,0), (2,0), (1,1) 尝试右: (0,1)='1', 未访问 -> DFS(0,1) visited[0][1]=true 继续探索... 遍历完成: ans = 2 (两个岛屿) 输出: 2

三、完整代码实现

classSolution{public:intnumIslands(vector<vector<char>>&grid){if(grid.empty())return0;intm=grid.size();intn=grid[0].size();vector<vector<bool>>visited(m,vector<bool>(n,false));// 方向:上、左、下、右intdir[4][2]={{-1,0},{0,-1},{1,0},{0,1}};function<void(int,int)>dfs=[&](inti,intj){// 如果已经访问过,直接返回if(visited[i][j])return;// 标记为已访问visited[i][j]=true;// 尝试四个方向for(intk=0;k<4;k++){intii=i+dir[k][0];intjj=j+dir[k][1];// 检查越界和是否为陆地if(ii<0||ii>=m||jj<0||jj>=n)continue;if(grid[ii][jj]=='0')continue;// 递归搜索dfs(ii,jj);}};intans=0;// 遍历整个网格for(inti=0;i<m;i++){for(intj=0;j<n;j++){// 找到未访问的陆地,就是新岛屿if(grid[i][j]=='1'&&!visited[i][j]){ans++;dfs(i,j);}}}returnans;}};

四、逐行解析

if(grid.empty())return0;
  • 处理空网格的特殊情况
intm=grid.size();intn=grid[0].size();vector<vector<bool>>visited(m,vector<bool>(n,false));
  • m, n:网格的行数和列数
  • visited:记录每个位置是否被访问过
intdir[4][2]={{-1,0},{0,-1},{1,0},{0,1}};
  • 四个方向的偏移量:上、左、下、右
function<void(int,int)>dfs=[&](inti,intj){
  • 定义 DFS 函数,用 lambda 方便递归调用
if(visited[i][j])return;visited[i][j]=true;
  • 如果已经访问过,直接返回(避免重复访问)
  • 否则标记为已访问
for(intk=0;k<4;k++){intii=i+dir[k][0];intjj=j+dir[k][1];if(ii<0||ii>=m||jj<0||jj>=n)continue;if(grid[ii][jj]=='0')continue;dfs(ii,jj);}
  • 遍历四个方向
  • 越界检查和是否为陆地的检查
  • 递归搜索相邻的陆地
if(grid[i][j]=='1'&&!visited[i][j]){ans++;dfs(i,j);}
  • 如果遇到未访问的陆地,说明发现了新岛屿
  • ans++,然后从该位置开始 DFS 标记整个岛屿

五、DFS 的原理

DFS 的核心思想:沿着一条路走到底,然后回溯。 对于岛屿问题: 1. 从起点出发,把起点标记为已访问 2. 依次尝试四个方向 3. 如果相邻位置是未访问的陆地,递归进入 4. 每个位置只会被访问一次 类似"染色"的过程: - 找到一个未染色陆地,染成新颜色 - 递归把所有相邻的陆地染成同样的颜色 - 继续找下一个未染色陆地

六、与并查集对比

维度DFS并查集
代码复杂度简单较复杂
时间复杂度O(m*n)O(m*n * alpha)
空间复杂度O(m*n)O(m*n)
实现方式递归或栈数组 + 路径压缩
适用场景岛屿、连通区域需要动态合并的场景

七、复杂度分析

方法时间复杂度空间复杂度备注
DFSO(m*n)O(m*n)推荐,递归深度最多 m*n
BFSO(m*n)O(m*n)用队列存储
并查集O(m*n)O(m*n)较复杂
迭代 DFSO(m*n)O(m*n)避免递归栈溢出

详细分析:

时间复杂度: 每个格子最多被访问一次 每次访问时进行常数次操作 总计:O(m*n) 空间复杂度: visited 数组:O(m*n) 递归栈深度:最坏 O(m*n)(当整个网格都是陆地时) 总计:O(m*n)

八、边界情况分析

情况处理方式
空网格return 0
全是水 (‘0’)return 0
全是陆地 (‘1’)return 1
单个陆地return 1
网格只有一行正常处理
网格只有一列正常处理

示例:全是水

grid = [ ['0','0','0'], ['0','0','0'] ] 遍历: 所有位置都是 '0',不满足 grid[i][j] == '1' ans = 0 输出: 0

示例:全是陆地

grid = [ ['1','1','1'], ['1','1','1'] ] 遍历: (0,0): 发现新岛屿,ans=1,DFS 标记整个网格 剩余位置都已访问 输出: 1

九、面试追问 FAQ

问题回答要点
Q: 为什么需要 visited 数组?防止重复访问同一个位置,导致无限递归或重复计数
Q: 能否不用 visited?可以原地修改 grid,但会破坏输入数据
Q: 递归深度太大怎么办?用栈模拟递归,或者 BFS
Q: 时间复杂度为什么是 O(m*n)?每个格子最多被访问一次
Q: 能否用 BFS 代替 DFS?可以,BFS 用队列,DFS 用栈或递归
Q: 四个方向的顺序重要吗?不重要,只要遍历完四个方向即可

十、相关题目

题目编号题目名称难度核心差异
200岛屿数量中等基础题,统计岛屿个数
695岛屿的最大面积中等求最大岛屿面积
463岛屿的周长简单求岛屿周长
694不同岛屿的数量困难求不同形状岛屿数量
剑指 Offer 13机器人的运动范围中等BFS/DFS + 条件限制
79单词搜索中等DFS 回溯

十一、总结

要点内容
核心思想遍历网格,遇到未访问的陆地就计数并 DFS 标记
关键数据结构visited 数组,防止重复访问
方向数组dir[4][2] = {{-1,0},{0,-1},{1,0},{0,1}}
时间复杂度O(m*n)(每个格子最多访问一次)
空间复杂度O(m*n)(visited + 递归栈)
变形求岛屿面积(统计岛屿内格子数)、求岛屿周长
易错点越界检查、visited 判断

岛屿数量是经典的连通区域问题,通过 DFS/BFS 遍历网格,标记已访问的陆地,统计连通区域的数量。


http://www.jsqmd.com/news/899106/

相关文章:

  • API聚合平台从比价到选型:2026年AI大模型API中转站选购核心逻辑与实战评估
  • StreamFX终极指南:5个核心功能让你的直播画面瞬间升级
  • ChatGPT写JD真的靠谱吗?一线大厂HR总监实测127份JD后,给出这5条铁律
  • 别再只玩Arduino了!用ESP32-WROOM-32做个智能家居网关,保姆级环境搭建与引脚配置指南
  • 从零到一:基于涂鸦Wi-Fi模组的智能红外遥控器DIY全攻略
  • 2026 海南封关红利凸显,进出口贸易热度飙升!合规代办服务精选指南 - 资讯纵览
  • 2026四向穿梭车怎么选?越来越多企业开始关注“系统能力”
  • 五大国产 AI App 大横评:谁是日常使用、文案写作、文件处理等场景的最佳之选?
  • yolo26模型部署在rk3588
  • 7×24小时不打烊:数字人智能客服如何重塑政务服务“最后一公里“
  • 2026年5月工程信息平台:中项网重构工程行业获客逻辑 - GrowthUME
  • 义乌网店饰品批发厂家实力对比:五大硬指标逐一解析 - 资讯快报
  • 创业公司如何建立合作伙伴生态
  • 学术写作提质新思路:paperxie 毕业论文 AI 创作功能实操使用解析
  • 如何快速掌握C++游戏开发:基于Cocos2d-x的植物大战僵尸完整实战指南
  • 2026年饶阳钢格栅采购选型与合规落地全攻略 - 资讯纵览
  • MCP测试v4
  • 2026年闵行那些靠谱的回收黄金加工厂家揭秘 - 资讯纵览
  • 火爆分享使用Taotoken后API调用延迟与稳定性的真实体感
  • 电商关键词挖掘:Java 爬虫抓取 1688 推荐搜索词
  • 高端腕表维修深度测评|从设备、技术、服务四维实测,解析盛时出圈原因 - 资讯快报
  • 高效搞定学术文稿:paperxie 论文智能创作功能实操用法分享
  • Cache主存地址映射实战:从课后题到三种映射方式的地址格式设计
  • 深圳电子元器件供应商哪家种类全
  • 搭上鸿蒙“快车”,ToDesk远控如何用全场景体验点燃效率革命?
  • Qwen-Edit-2509多角度图像生成:用自然语言指令重塑视觉创作
  • MCP博客园工具集成测试v2
  • 2026年河北钢格栅行业深度攻略:选型、合规、品牌与落地全指南 - 资讯纵览
  • 2026重庆全屋定制公司推荐排行榜 五大高端品牌实力深度测评 - 资讯快报
  • 2026年驱蚊雾森系统排名:最新权威排名与专业指南。 - 资讯快报