题目
思路
1.确定递归函数的返回值及参数:
返回值是void,参数这里还是先设定两个全局变量。一个是path存放符合条件单一结果。如:(1,2)。一个是result,是所有path的集合[(1,2),(1,3)…]。
此外再设定一个sum,用来记录path的和。
2.回溯函数终止条件
sum==target时return
3.单层搜索的过程
用path保存当前节点。
sum+=当前值
搜索当前节点的所有子节点
回溯,remove
4.剪枝优化
我们先排好序。
当sum+当前的值大于target的时候,因为已经排好了序,所以当前节点后面的所有子节点都不需要遍历了。
代码
import java.util.LinkedList;
//leetcode submit region begin(Prohibit modification and deletion)
class Solution {
List<List<Integer>> res = new ArrayList<>();
List<Integer> path = new ArrayList<>();
public List<List<Integer>> combinationSum(int[] candidates, int target) {
Arrays.sort(candidates);
backTracking(candidates, target, 0, 0);
return res;
}
public void backTracking(int[] candidates, int target, int sum, int startIndex) {
if (sum == target) {
res.add(new ArrayList<>(path));
return;
}
for (int i = startIndex; i < candidates.length; i++) {
if (sum + candidates[i] > target) break;
path.add(candidates[i]);
sum += candidates[i];
backTracking(candidates, target, sum, i);
path.remove(path.size() - 1);
sum -= candidates[i];
}
}
}
//leetcode submit region end(Prohibit modification and deletion)
我的错误
- res.add(new ArrayList<>(path)); //我一开始写成了res.add(path);
直接add path是错误的,因为path是引用类型,res保存的其实是path的地址。后续因为path会remove掉里面的元素,这时候res也会同等变化。所以我们需要new一个path的副本出来。
- 没有使用startIndex,导致出现了重复的结果,比如(2,2,3) 和(3,2,2)
startIndex作用:是用来确保子节点从哪一个值开始取的。