1. 问题背景与理解
"岛屿数量"是LeetCode上经典的图论问题(编号200),也是面试中的高频考题。我第一次遇到这个问题是在亚马逊的面试中,面试官在白板上画了一个由'1'和'0'组成的网格,要求我计算其中岛屿的数量。当时因为对深度优先搜索(DFS)的理解不够深入,导致解题过程磕磕绊绊。经过大量练习后,我发现这个问题是理解图遍历算法的绝佳切入点。
岛屿问题的标准定义是:给定一个由'1'(陆地)和'0'(水)组成的二维网格,计算其中岛屿的数量。岛屿由水平或垂直方向上相邻的陆地连接形成,假设网格四周都被水包围。例如:
code复制输入:
[
["1","1","0","0","0"],
["1","1","0","0","0"],
["0","0","1","0","0"],
["0","0","0","1","1"]
]
输出:3
这个问题看似简单,但涉及几个关键考察点:
- 二维数组的遍历方式
- 深度优先搜索(DFS)或广度优先搜索(BFS)的实现
- 避免重复计数的技巧(即如何标记已访问的节点)
- 边界条件的处理
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 深度优先搜索解法详解
2.1 基础DFS实现
DFS是解决岛屿问题的自然选择——当我们遇到一个'1'时,以此为起点向四周探索所有相连的陆地,就像墨水在纸上扩散一样。以下是Python实现的核心代码:
python复制def numIslands(grid):
if not grid:
return 0
count = 0
rows, cols = len(grid), len(grid[0])
for i in range(rows):
for j in range(cols):
if grid[i][j] == '1':
count += 1
dfs(grid, i, j)
return count
def dfs(grid, i, j):
if i < 0 or j < 0 or i >= len(grid) or j >= len(grid[0]) or grid[i][j] != '1':
return
grid[i][j] = '#' # 标记为已访问
dfs(grid, i+1, j)
dfs(grid, i-1, j)
dfs(grid, i, j+1)
dfs(grid, i, j-1)
关键点说明:
- 主函数中双重循环遍历每个单元格
- 遇到'1'时计数器加1,并启动DFS
- DFS递归访问上下左右四个方向
- 将访问过的'1'标记为'#'避免重复计数
注意:直接修改输入数组在某些场景下可能不被允许,面试时应与面试官确认。替代方案是使用单独的visited矩阵。
2.2 时间复杂度分析
假设网格大小为M×N:
- 每个节点最多被访问一次(被标记后不再处理)
- 每个节点访问时的操作是O(1)的
- 因此
