📘题目描述
给你一个由 '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
💡解题思路:深度优先搜索(DFS)
✅核心思想
-
遍历网格中每一个位置
(i, j)
-
如果当前是
'1'
,说明是一个新岛屿 -
从这个点出发用 DFS 把整个岛“淹掉”——把它连通的所有
'1'
都变成'0'
-
每次启动 DFS 就说明发现一个新岛屿,
count += 1
✅Python 实现
class Solution:
def numIslands(self, grid: List[List[str]]) -> int:
if not grid:
return 0
rows, cols = len(grid), len(grid[0])
count = 0
def dfs(r, c):
# 边界 & 水 or 已访问
if r < 0 or c < 0 or r >= rows or c >= cols or grid[r][c] == '0':
return
# 标记访问
grid[r][c] = '0'
# 淹没四个方向
dfs(r - 1, c)
dfs(r + 1, c)
dfs(r, c - 1)
dfs(r, c + 1)
for i in range(rows):
for j in range(cols):
if grid[i][j] == '1':
dfs(i, j) # 从这里开始“淹岛”
count += 1
return count
🔁可选拓展解法:BFS 版本
也可以用 BFS(队列)代替 DFS,思路类似,从一个 '1'
点开始把整块岛屿都“标记/淹掉”。
⏱️复杂度分析
项目 | 复杂度 | 说明 |
---|---|---|
时间复杂度 | O(m × n) | 每个点最多访问一次 |
空间复杂度 | O(m × n) | 最坏情况下递归栈或队列的大小 |
🧱易错点总结
易错点 | 正确做法说明 |
---|---|
未判断边界导致数组越界 | 加上 r < 0 or c < 0 ... 的判断 |
忘记标记访问的 '1' | grid[r][c] = '0' 或用 visited 集 |
对于不同岛屿没有累加 count | 每次 DFS 前都 count += 1 |
🎯总结
-
本题是图遍历中经典的“连通块数量”问题。
-
DFS 和 BFS 均可解决,推荐先掌握 DFS。
-
与本题类似的还有:
-
被围绕的区域(LeetCode 130)
-
太平洋大西洋水流问题(LeetCode 417)
-