← 返回首页
algorithm-pattern-python/basic_algorithm/graph/bfs_dfs.md at master · dashidhy/algorithm-pattern-python · GitHub
Skip to content

Navigation Menu

Toggle navigation
Sign in
Appearance settings
Search or jump to...

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Include my email address so I can be contacted

Saved searches

Use saved searches to filter your results more quickly

Appearance settings
Resetting focus

Latest commit

 

History

History
235 lines (183 loc) · 6.4 KB
 master
Top

File metadata and controls

  • Preview
  • Code
  • Blame
235 lines (183 loc) · 6.4 KB

深度优先搜索,广度优先搜索

深度优先搜索模板

  • 先序,递归
def DFS(x): visit(x) for n in neighbor(x): if not visited(n): DFS(n) return
  • 先序,迭代,出栈时访问
def DFS(x): dfs = [x] # implement by a stack while dfs: v = dfs.pop() if not visited(v): visit(v) for n in neighbor(v): if not visited(n): dfs.append(n) return
  • 后序,递归
def DFS(x): # used when need to aggregate results from children discovering(x) for n in neighbor(x): if not discovering(n) and not visited(n): DFS(n) visit(x) return

广度优先搜索模板

相对于 dfs 可能收敛更慢,但是可以用来找不带权的最短路径

  • 以结点为单位搜索
def BFS(x): visit(x) bfs = collections.deque([x]) while bfs: v = bfs.popleft() for n in neighbor(v): if not visited(n): visit(n) bfs.append(n) return
  • 以层为单位搜索,典型应用是找不带权的最短路径
def BFS(x): visit(x) bfs = collections.deque([x]) while bfs: num_level = len(bfs) for _ in range(num_level) v = bfs.popleft() for n in neighbor(v): if not visited(v): visit(n) bfs.append(n) return

例题

给定一个二维矩阵,矩阵中元素 -1 表示墙或是障碍物,0 表示一扇门,INF (2147483647) 表示一个空的房间。你要给每个空房间位上填上该房间到最近门的距离,如果无法到达门,则填 INF 即可。

  • 思路:典型的多源最短路径问题,将所有源作为 BFS 的第一层即可
inf = 2147483647 class Solution: def wallsAndGates(self, rooms: List[List[int]]) -> None: """ Do not return anything, modify rooms in-place instead. """ if not rooms or not rooms[0]: return M, N = len(rooms), len(rooms[0]) bfs = collections.deque([]) for i in range(M): for j in range(N): if rooms[i][j] == 0: bfs.append((i, j)) dist = 1 while bfs: num_level = len(bfs) for _ in range(num_level): r, c = bfs.popleft() if r - 1 >= 0 and rooms[r - 1][c] == inf: rooms[r - 1][c] = dist bfs.append((r - 1, c)) if r + 1 < M and rooms[r + 1][c] == inf: rooms[r + 1][c] = dist bfs.append((r + 1, c)) if c - 1 >= 0 and rooms[r][c - 1] == inf: rooms[r][c - 1] = dist bfs.append((r, c - 1)) if c + 1 < N and rooms[r][c + 1] == inf: rooms[r][c + 1] = dist bfs.append((r, c + 1)) dist += 1 return

在给定的 01 矩阵 A 中,存在两座岛 (岛是由四面相连的 1 形成的一个连通分量)。现在,我们可以将 0 变为 1,以使两座岛连接起来,变成一座岛。返回必须翻转的 0 的最小数目。

  • 思路:DFS 遍历连通分量找边界,从边界开始 BFS找最短路径
class Solution: def shortestBridge(self, A: List[List[int]]) -> int: M, N = len(A), len(A[0]) neighors = ((-1, 0), (1, 0), (0, -1), (0, 1)) dfs = [] bfs = collections.deque([]) for i in range(M): for j in range(N): if A[i][j] == 1: # start from a 1 dfs.append((i, j)) break if dfs: break while dfs: r, c = dfs.pop() if A[r][c] == 1: A[r][c] = -1 for dr, dc in neighors: nr, nc = r + dr, c + dc if 0<= nr < M and 0 <= nc < N: if A[nr][nc] == 0: # meet and edge A[nr][nc] = -2 bfs.append((nr, nc)) elif A[nr][nc] == 1: dfs.append((nr, nc)) flip = 1 while bfs: num_level = len(bfs) for _ in range(num_level): r, c = bfs.popleft() for dr, dc in neighors: nr, nc = r + dr, c + dc if 0<= nr < M and 0 <= nc < N: if A[nr][nc] == 0: A[nr][nc] = -2 bfs.append((nr, nc)) elif A[nr][nc] == 1: return flip flip += 1
class Solution: def slidingPuzzle(self, board: List[List[int]]) -> int: next_move = { 0: [1, 3], 1: [0, 2, 4], 2: [1, 5], 3: [0, 4], 4: [1, 3, 5], 5: [2, 4] } start = tuple(itertools.chain(*board)) target = (1, 2, 3, 4, 5, 0) if start == target: return 0 SPT = set([start]) bfs = collections.deque([(start, start.index(0))]) step = 1 while bfs: num_level = len(bfs) for _ in range(num_level): state, idx0 = bfs.popleft() for next_step in next_move[idx0]: next_state = list(state) next_state[idx0], next_state[next_step] = next_state[next_step], next_state[idx0] next_state = tuple(next_state) if next_state == target: return step if next_state not in SPT: SPT.add(next_state) bfs.append((next_state, next_step)) step += 1 return -1

Footer

© 2026 GitHub, Inc.