DFS是递归的天然表达,岛屿计数、连通分量、周长计算的核心
深度优先搜索(DFS, Depth-First Search)从起点出发,沿一条路径尽可能深入,直到无法继续再回溯。DFS 用递归或栈实现,适合解决连通性问题、路径搜索、拓扑排序等。DFS 不保证最短路径,但在空间效率和实现简洁性上往往优于 BFS。
# 四方向(上下左右)
directions = [(0, 1), (0, -1), (1, 0), (-1, 0)]
# 八方向(含对角线)
directions = [(-1,-1),(-1,0),(-1,1),(0,-1),(0,1),(1,-1),(1,0),(1,1)]
# 边界检查
def in_bounds(r, c, rows, cols):
return 0 <= r < rows and 0 <= c < cols
def dfs(grid, r, c, visited):
rows, cols = len(grid), len(grid[0])
# 边界检查 + 已访问检查
if not (0 <= r < rows and 0 <= c < cols):
return
if (r, c) in visited or grid[r][c] == '0':
return
visited.add((r, c)) # 或 grid[r][c] = '0' (原地修改)
# 四方向递归
for dr, dc in [(0,1),(0,-1),(1,0),(-1,0)]:
dfs(grid, r+dr, c+dc, visited)
题目描述:给你一个由 '1'(陆地)和 '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 not (0 <= r < rows and 0 <= c < cols) or grid[r][c] != '1':
return
grid[r][c] = '0'
for dr, dc in [(0,1),(0,-1),(1,0),(-1,0)]:
dfs(r + dr, c + dc)
for r in range(rows):
for c in range(cols):
if grid[r][c] == '1':
count += 1
dfs(r, c)
return count
时间复杂度:O(m×n)
空间复杂度:O(m×n) — 递归栈
题目描述:给定一个包含 0 和 1 的二维数组,找到最大的岛屿面积。岛屿是 1 的连通区域。
class Solution:
def maxAreaOfIsland(self, grid: List[List[int]]) -> int:
rows, cols = len(grid), len(grid[0])
def dfs(r, c):
if not (0 <= r < rows and 0 <= c < cols) or grid[r][c] != 1:
return 0
grid[r][c] = 0
return 1 + dfs(r+1,c) + dfs(r-1,c) + dfs(r,c+1) + dfs(r,c-1)
max_area = 0
for r in range(rows):
for c in range(cols):
if grid[r][c] == 1:
max_area = max(max_area, dfs(r, c))
return max_area
时间复杂度:O(m×n)
空间复杂度:O(m×n)
题目描述:给定一个二维网格,1 表示陆地,0 表示水域。网格中的格子水平和垂直相连。计算岛屿的周长。
class Solution:
def islandPerimeter(self, grid: List[List[int]]) -> int:
rows, cols = len(grid), len(grid[0])
perimeter = 0
for r in range(rows):
for c in range(cols):
if grid[r][c] == 1:
for dr, dc in [(0,1),(0,-1),(1,0),(-1,0)]:
nr, nc = r + dr, c + dc
if not (0 <= nr < rows and 0 <= nc < cols) or grid[nr][nc] == 0:
perimeter += 1
return perimeter
时间复杂度:O(m×n)
空间复杂度:O(1)
并查集(Union-Find)是解决连通性问题的另一种利器,与DFS/BFS殊途同归,但在某些场景下更高效,特别是需要动态合并集合时。
class UnionFind:
def __init__(self, n):
self.parent = list(range(n))
self.rank = [0] * n
self.count = n # 连通分量数
def find(self, x):
if self.parent[x] != x:
self.parent[x] = self.find(self.parent[x]) # 路径压缩
return self.parent[x]
def union(self, x, y):
px, py = self.find(x), self.find(y)
if px == py:
return False
# 按秩合并
if self.rank[px] < self.rank[py]:
px, py = py, px
self.parent[py] = px
if self.rank[px] == self.rank[py]:
self.rank[px] += 1
self.count -= 1
return True