所谓的回溯,实际上就是一个决策树的遍历过程,一种选优搜索法,又称试探法。利用试探性的方法,在包含问题所有解的解空间树中,将可能的结果搜索一遍,从而获得满足条件的解。搜索过程采用深度遍历策略,并随时判定结点是否满足条件要求,满足要求就继续向下搜索,若不满足要求则回溯到上一层,这种解决问题的方法称为回溯法。
经常刷leetcode的同学应该深有感触。其他的基本定义这里就不做说明了,为了方便其他人了解,这里会提供一个具体的case,然后一步步带大家深入浅出的理解回溯算法。
废话不多说,直接上回溯算法框架。解决一个回溯问题,我们正常思考 3 个问题:
1、路径:也就是已经做出的选择。
2、选择列表:也就是你当前可以做的选择。
3、结束条件:也就是到达决策树底层,无法再做选择的条件。
代码方面,回溯算法的框架:
result = []
def backtrack(路径, 选择列表):
if 满足结束条件:
result.add(路径)
return
for 选择 in 选择列表:
做选择
backtrack(路径, 选择列表)
撤销选择
其核心就是 for 循环里面的递归,在递归调用之前「做选择」,在递归调用之后「撤销选择」,怎么理解这个呢,看一下下面的例子就知道了。
例子:给定一个无重复元素的数组 candidates
和一个目标数 target
,找出 candidates
中所有可以使数字和为 target
的组合。
输入:candidates = [2,3,5],
target = 8,
所求解集为:
[
[2,2,2,2],
[2,3,3],
[3,5]
]
我们按照上面的套路模版,来一步步解题:
1:题目给出的算法结构为
c