第七章:搜索:深度、广度与剪枝
搜索算法是算法竞赛中的基石,它模仿了人类解决问题的试探过程,是解决许多“看似无从下手”问题的“暴力”美学。无论是走迷宫、解数独,还是寻找图中的路径,其核心都是搜索。本章将深入探讨两种最核心的搜索策略——深度优先搜索(DFS)和广度优先搜索(BFS),并介绍至关重要的优化技巧——剪枝。
7.1 深度优先搜索 (DFS) 与回溯法
深度优先搜索(DFS, Depth-First Search)是一种“不撞南墙不回头”的搜索策略。想象一下在走一个巨大的迷宫,你总是沿着一条路走到黑,直到遇到死胡同,才返回上一个路口,选择另一条没走过的路继续探索。这种“一条道走到黑”再“返回”尝试其他路径的方式,就是DFS的核心思想。
在程序实现上,DFS通常借助递归来完成,利用函数调用栈来保存“路口”信息,从而在“撞墙”后能顺利返回。当DFS用于寻找所有可能的解,并在探索过程中动态地构建和撤销选择时,它就体现为回溯法。可以说,回-溯法是DFS在求解组合、排列、子集、棋盘等问题时的具体应用范式。
DFS的核心模板(递归实现):
Python
# visited 通常是一个集合(set),用于记录已经访问过的节点,防止死循环
visited = set()
def dfs(node, current_path):
# 1. 到达终点或满足特定条件,记录结果
if is_solution(node):
add_to_results(current_path)
return
# 2. 将当前节点标记为已访问
visited.add(node)
# 3. 遍历当前节点的所有邻居
for neighbor in get_neighbors(node):
# 4. 如果邻居未被访问过
if neighbor not in visited:
# 做出选择:将邻居加入路径
current_path.append(neighbor)
# 递归进入下一层
dfs(neighbor, current_path)
# 撤销选择(回溯):将邻居从路径中移除,以便尝试其他分支
current_path.pop()
# 注意:在某些图中,是否移除visited标记取决于题目要求
# 如果是寻找所有路径,可能需要移除,如果是防止重复访问,则不应移除
# visited.remove(node)
实战案例:全排列问题
给定一个不含重复数字的数组 nums,返回其所有可能的全排列。
分析: 这正是回

最低0.47元/天 解锁文章
628

被折叠的 条评论
为什么被折叠?



