描述:
给你一个由 '1'
(陆地)和 '0'
(水)组成的的二维网格,请你计算网格中岛屿的数量。
岛屿总是被水包围,并且每座岛屿只能由水平方向和/或竖直方向上相邻的陆地连接形成。
此外,你可以假设该网格的四条边均被水包围
思路:
-
遍历整个网格:
-
遇到
'1'
(陆地)时,说明找到一个新岛屿,岛屿数 +1。 -
然后通过 DFS 递归访问该陆地的 上下左右 相邻陆地,并将访问过的陆地标记为
'0'
,防止重复计数。
-
-
继续遍历整个网格,直到所有的岛屿都被访问。
代码:
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):
# 边界条件判断 & 已访问的陆地
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': # 遇到新的岛屿
count += 1
dfs(i, j) # 通过 DFS 将整座岛屿淹没
return count
示例:
1 1 0 0 0
1 1 0 0 0
0 0 1 0 0
0 0 0 1 1
第一步:遇到 (0,0),开始 DFS
# 递归淹没第一块岛屿
1 1 0 0 0 -> 0 0 0 0 0
1 1 0 0 0 0 0 0 0 0
0 0 1 0 0 0 0 1 0 0
0 0 0 1 1 0 0 0 1 1
第二步:遇到 (2,2),DFS
# 递归淹没第二块岛屿
0 0 0 0 0 -> 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 1 0 0 0 0 0 0 0
0 0 0 1 1 0 0 0 1 1
第三步:遇到 (3,3),DFS
# 递归淹没第三块岛屿
0 0 0 0 0 -> 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 1 1 0 0 0 0 0
输出:3
复杂度分析:
时间复杂度
-
O(m × n),其中 mmm 和 nnn 分别是网格的行数和列数。每个节点最多访问一次。
空间复杂度
-
O(m × n)(最坏情况下),当整个网格都是陆地时,递归栈深度最大为 m×nm \times nm×n。