回溯总结:
相当于暴力for循环,其目的用递归控制for循环嵌套的数量。当剪枝时,就可以使得嵌套数量减少。把回溯问题抽象一颗树比较好懂。并且使得代码更简洁。
对于组合问题,什么时候需要startIndex呢?
在一个集合求组合时,需要startidx ;
如果是多个集合取组合,各个集合不互相影响,那么就不用startidx.
去重问题
组合总和2
题意:集合元素会有重复,但要求解集不能包含重复的组合。
去重分为:
“树枝去重”和“树层去重”
去重前一般需要排序,看是否需要排序。
在图中将used的变化用橘黄色标注上,可以看出在candidates[i] == candidates[i - 1]相同的情况下:
used[i - 1] == true,说明同一树枝candidates[i - 1]使用过
used[i - 1] == false,说明同一树层candidates[i - 1]使用过
电话号码的字母组合
已知手机按键代表的字母,遍历手机按键,求组合。
切割问题
[回文串切割](https://programmercarl.com/0131.%E5%88%86%E5%89%B2%E5%9B%9E%E6%96%87%E4%B8%B2.html)
我列出如下几个难点:
切割问题其实类似组合问题
如何模拟那些切割线
切割问题中递归如何终止
在递归循环中如何截取子串
如何判断回文
模拟切割线 ,起点是startidx , 终点是i ;
切割问题递归终止 :如果startidx到达nums.size那么就到达了终止条件
截取子串:从startidx到 i 截取。
判断回文简单。
子集问题:
子集
在树形结构中子集问题是要收集所有节点的结果,而组合问题是收集叶子节点的结果。
排列问题:
与组合问题不同的是:
另外去重和组合问题一样
每层都是从0开始搜索而不是startIndex
需要used数组记录path里都放了哪些元素了