leetcode回溯法总结

2018.7.30

前文:回溯法和dfs是不一样的,回溯法有自己很独特的模板,dfs是一种思想,回溯法是dfs的一种实现。
先来看回溯法的典型题型:

Find a path to success 有没有解
Find all paths to success 求所有解
1.求所有解的个数 2. 求所有解的具体信息
Find the best path to success 求最优解

对应的三种模板:

第一种,返回值是true/false。
第二种,求个数,设全局counter,返回值是void;求所有解信息,设result,返回值void。
第三种,设个全局变量best,返回值是void。

一般情况下,第二种居多,第二种也是最难理解了,得到了所有可行的解,自然可以得出这些解中的最优解。

下面给出第二种的常见题型和解答:
77. Combinations https://leetcode.com/problems/combinations/description/
在这里插入图片描述
在这里插入图片描述
Combination Sum https://leetcode.com/problems/combination-sum/description/
在这里插入图片描述
在这里插入图片描述

Subsets : https://leetcode.com/problems/subsets/
在这里插入图片描述
在这里插入图片描述

Subsets II (contains duplicates) : https://leetcode.com/problems/subsets-ii/
在这里插入图片描述
在这里插入图片描述

Permutations : https://leetcode.com/problems/permutations/
在这里插入图片描述
在这里插入图片描述

总结上述的这些题型就有一个特点,找出满足给定条件的集合,实际就是满足条件的结果树,进行回溯法遍历即可。
如果题目说,给定一个集合,然后给某种条件,去找到满足条件的所有结果,这一类都可以用回溯法来完成。
这一类的经典模板如下:
在这里插入图片描述

ans用来保存中间结果,这里需要说明的是ans是拷贝赋值,也就是说叶子节点的深搜不影响到父节点,所以父节点只需要将当前节点插入的数据弹出即可,那么遍历下一个情况的时候,ans就是空的了,相当于当前节点弹出,进行到下一个节点了。
注意点:
start,遍历的起始位置
ans,中间结果的保存
pop_back,回溯到上一层

那么这种回溯的模板和dfs有什么区别呢?

dfs可以简单理解为中序遍历,其实是一种遍历的方法,它保留了所有的节点信息,例如遍历到叶子节点,然后递归回来,继续遍历右子数,再去递归到叶子节点,每个节点的数据都保存了一遍。

而对于回溯,和dfs不同的是,它往往使用的是循环,循环遍历结果的初始可能性。
两者区别也不是那么大,只是某一类情况,用回溯更加清楚直接。

猜你喜欢

转载自blog.csdn.net/u012414189/article/details/84886893