pythonfrom collections import deque
def bfs(起始点):
# 初始化队列和访问标记
queue = deque()
queue.append(起始点)
visited = set()
visited.add(起始点)
while queue:
# 弹出当前节点
node = queue.popleft()
# 处理当前节点(例如记录路径、判断条件等)
处理当前节点
# 遍历相邻节点
for neighbor in 获取相邻节点(node):
if neighbor 未越界 and neighbor 未访问:
queue.append(neighbor)
visited.add(neighbor) # 必须在此处标记已访问
解题思路:
与DFS不同,BFS会逐层向外扩散搜索。每次遇到陆地 '1'
时,将其加入队列,并标记为已访问,直到队列为空,完成一个岛屿的搜索。
visited
)pythonfrom collections import deque
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':
# BFS开始
queue = deque()
queue.append((i, j))
grid[i][j] = '0' # 标记为已访问
while queue:
x, y = queue.popleft()
# 四个方向扩散
for dx, dy in [(-1,0), (1,0), (0,-1), (0,1)]:
nx, ny = x + dx, y + dy
# 检查是否合法且为陆地
if 0 <= nx < rows and 0 <= ny < cols and grid[nx][ny] == '1':
queue.append((nx, ny))
grid[nx][ny] = '0' # 入队时立即标记
count += 1
return count
队列的核心作用:
保证按层级顺序处理节点,类似“波纹扩散”效果。
访问标记的时机:
必须在入队时标记,而非出队时。若在出队时标记,会导致同一节点被重复加入队列。
时间复杂度:
O(M×N),与DFS相同,但空间复杂度在最坏情况下(如全为陆地)为 O(min(M,N)),因为队列中最多同时存储对角线上的节点。
队列实现选择:
Python中用deque
实现高效的头尾操作,避免用列表模拟队列(pop(0)
是O(n)操作)。
方向遍历技巧:
用方向数组dx, dy
表示四个方向,代码更简洁。
空间优化讨论:
若不允许修改输入数据,需声明visited
矩阵;若允许修改,直接修改原数组可节省空间。
解释BFS与DFS的选择:
BFS适合找最短路径,DFS适合找连通性(本题两者均可)。若面试官追问差异,可结合时间复杂度展开。
掌握BFS模板后,可解决大多数层级扩散类问题。核心是理解队列的“先进先出”特性,以及正确处理访问标记的时机。
本文作者:Dong
本文链接:
版权声明:本博客所有文章除特别声明外,均采用 CC BY-NC。本作品采用《知识共享署名-非商业性使用 4.0 国际许可协议》进行许可。您可以在非商业用途下自由转载和修改,但必须注明出处并提供原作者链接。 许可协议。转载请注明出处!