【算法专题三】回溯法/DFS

算法思想

定义

回溯法(探索与回溯法)是一种选优搜索法,按选优条件向前搜索,以达到目标。但当探索到某一步时,发现原先选择并不优或达不到目标,就退回一步重新选择,这种走不通就退回再走的技术为回溯法,而满足回溯条件的某个状态的点称为“回溯点”

适用范围

有许多问题,当需要找出它的解集(全部解)或者要求回答什么解是满足某些约束条件的最优解时,往往要使用回溯法。

  • 有组织的穷举式搜索

回溯法的基本做法是搜索或者有的组织穷尽搜索。它能避免搜索所有的可能性。即避免不必要的搜索。这种方法适用于解一些组合数相当大的问题。

  • 搜索解空间树

回溯法在问题的解空间树中,按深度优先策略,从根结点出发搜索解空间树。算法搜索至解空间树的任意一点时,先判断该结点是否包含问题的解。如果肯定不包含(剪枝过程),则跳过对该结点为根的子树的搜索,逐层向其祖先结点回溯;否则,进入该子树,继续按深度优先策略搜索。

为了实现回溯,我们先弄明白以下两个问题:

1)首先应该明确问题的解空间。

2)其次是组织解空间以便它能用以被搜索

回溯算法框架

解决⼀个回溯问题,实际上就是⼀个决策树的遍历过程。只需要思考 3 个问题:

  • 路径:也就是已经做出的选择。
  • 选择列表:也就是你当前可以做的选择。
  • 结束条件:也就是到达决策树底层,⽆法再做选择的条件。
result = []
def backtrack(路径, 选择列表):
	if 满⾜结束条件:
		result.add(路径)
		return
	
	for 选择 in 选择列表:
		做选择
		backtrack(路径, 选择列表)
		撤销选择
for 选择 in 选择列表:
	# 做选择
	将该选择从选择列表移除
	路径.add(选择)
	backtrack(路径, 选择列表)
	# 撤销选择
	路径.remove(选择)
	将该选择再加⼊选择列表

其核⼼就是 for 循环⾥⾯的递归,在递归调⽤之前「做选择」,在递归调⽤之后「撤销选择,特别简单。

写 backtrack 函数时,需要维护⾛过的「路径」和当前可以做的「选择列
表」,当触发「结束条件」时,将「路径」记⼊结果集。

递归要点

(1)递归参数
(2)终止条件
(3)递推工作
(4)返回值

其他参考

1.基本思想
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
2.迭代回溯的一般框架
在这里插入图片描述

3. 回溯法例题

【题目1】:矩阵中的路径(剑指offer-12)

【题目2:】机器人的运动范围

【题目3】:二叉树中和为某一值的路径(剑指offer-34)

【题目4】: 全排列(leetcode 46/47)

【题目5】:字符串的排列

【题目4】N皇后

给你⼀个 N×N 的棋盘,让你放置 N 个皇后,使得它们不能互相攻击。PS:皇后可以攻击同⼀⾏、同⼀列、左上左下右上右下四个⽅向的任意单位。参考解析

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值