图论 解题模板

适用场景

岛屿问题、拓扑排序、并查集、有向/无向图遍历

通用模板

网格 DFS(岛屿问题)

 
def dfs(grid, i, j):
 
    if i < 0 or i >= m or j < 0 or j >= n or grid[i][j] != '1':
 
        return
 
    grid[i][j] = '0'  # 标记已访问
 
    for di, dj in [(1,0),(-1,0),(0,1),(0,-1)]:
 
        dfs(grid, i+di, j+dj)
 

拓扑排序(课程表)

 
# BFS(Kahn)
 
indeg = [0] * n
 
graph = [[] for _ in range(n)]
 
for u, v in edges:
 
    graph[v].append(u)  # 前驱→后继
 
    indeg[u] += 1
 
q = deque([i for i in range(n) if indeg[i] == 0])
 
res = []
 
while q:
 
    node = q.popleft()
 
    res.append(node)
 
    for nei in graph[node]:
 
        indeg[nei] -= 1
 
        if indeg[nei] == 0: q.append(nei)
 
return res if len(res) == n else []
 

并查集

 
parent = list(range(n))
 
def find(x):
 
    while parent[x] != x:
 
        parent[x] = parent[parent[x]]  # 路径压缩
 
        x = parent[x]
 
    return x
 
def union(x, y):
 
    rx, ry = find(x), find(y)
 
    if rx == ry: return False
 
    parent[ry] = rx
 
    return True
 

复杂度总结

模式时间空间典型题
DFS/BFSO(m×n)O(m×n)岛屿数量、腐烂橘子
拓扑排序O(V+E)O(V+E)课程表
并查集O(α(n))O(n)冗余连接、省份数量

关键要点

  • 网格 DFS 注意边界检查顺序

  • 拓扑排序 = 有向无环图的线性排序

  • 并查集路径压缩 + 按秩合并

→ 查看该分类题目:LeetCode学习路线图 > 十二、图论


相似题对比

易混题对关键区别解法差异
200岛屿数量 vs 695岛屿最大面积计数 vs 求最大695 DFS返回面积,取max
207课程表 vs 210课程表II判环 vs 输出拓扑序207返回bool;210输出order
547省份数量 vs 684冗余连接无向图连通分量 vs 找环边DFS计数 vs 并查集union失败
200岛屿数量 vs 994腐烂橘子遍历一次 vs 多源BFS分层DFS染色 vs BFS逐分钟扩散

测试用例模板

 
# 基础功能
 
assert numIslands([
 
    ["1","1","1","1","0"],
 
    ["1","1","0","1","0"],
 
    ["1","1","0","0","0"],
 
    ["0","0","0","0","0"]
 
]) == 1
 
# 边界
 
assert numIslands([]) == 0                # 空网格
 
assert numIslands([["1"]]) == 1           # 单格
 
# 特殊
 
assert numIslands([["0"]]) == 0
 

关联题型

关联题型常见结合方式典型题目
回溯DFS回溯200岛屿数量, 79单词搜索
Dijkstra最小堆743网络延迟时间
队列BFS队列994腐烂橘子, 127单词接龙