从三个方面进行区分。
1. 参数
2. 终止条件
3.单层搜索
不去重
1.组合
组合,{1,2} == {2,1},所以每次选择的时候,树层上不能选择之前选过的元素。
参数:nums , startIndex(用来限制每次选取的位置
终止条件:文中说了几个为一组,或者有总和的限制的时候,就按照题目要求写就可以。收集的是叶子结点。
单层搜索:循环 i = startIndex ,然后 处理节点、递归、回溯
2.子集
子集,[1 ,2] == [2 ,1] ,所以同样树层上不能选取之前选过的元素
参数:nums,startIndex
终止条件:没有,见到收集,除非题目有特殊要求。收集的是每一个结点,而不是单纯的叶子节点。
单层搜索:循环 i = startIndex ,然后 处理节点、递归、回溯
3.排序
排序,[ 1,2] != [ 2,1] 。所以树层上是可以选取之前选过的元素的,(for循环中,i = 0)
但注意,正是由于可以选则之前选过的元素,所以要注意在树枝上,不能选取已经选过的元素。
参数:nums,used(用来判断该树枝上,是否已经使用过该元素
终止条件:path.size() == nums.size()
单层搜索:循环 i = 0 ,判断在树枝上该结点是否使用过。(used[i] == true),只用过就直接continue 。如果没使用过, 处理节点、递归、回溯
去重:
1.组合
需要排序:将相同的元素靠在一块,方便处理。
参数:nums,startIndex ,used 多了一个used数组,是用来判断 树层的
终止条件:和之前一样
单层搜索:循环 i = startIndex ,判断是否会重复取,(i >0 && num[i] == num[i - 1] && used[i - 1] == false)如果重复就continue,不重复, 处理节点、递归、回溯
2.子集
和组合的去重一样,就不详细写了。注意要排序。同时收割结果集的时候不用return
3.排序
排序的去重其实也一样。used。 千万记得排序啊。。
只是相对来说,排序在循环中有两个判断
1. 树层去重 (i >0 && num[i] == num[i - 1] && used[i - 1] == false)
2.树枝不能重复(used[i] == true)