文章目录
- 题目
- 思考
- 代码和注释
- 总结
题目
给你一个 无重复元素 的整数数组 candidates 和一个目标整数 target ,找出 candidates 中可以使数字和为目标数 target 的 所有 不同组合 ,并以列表形式返回。你可以按 任意顺序 返回这些组合。
candidates 中的 同一个 数字可以 无限制重复被选取 。如果至少一个数字的被选数量不同,则两种组合是不同的。
对于给定的输入,保证和为 target 的不同组合数少于 150 个。
来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/combination-sum
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
思考
- 1、其实写到这对回溯已经有了认识题型的基本能力了
- 2、组合相关的题目【这题是可以重新使用】,那我就是在每层树都需要保留上层元素的值。=》那我们就要在startIdx中做文章了
- 3、这里也对深度和广度有了新的理解,总结见
代码和注释
/**
回溯
1、确定递归函数的参数
2、确定终止条件
3、每轮递归要干的事情
*/
class Solution {
// 1、收集路径的结果集
LinkedList<Integer> path = new LinkedList<>();
// 2、结果集
List<List<Integer>> res = new ArrayList<>();
public List<List<Integer>> combinationSum(int[] candidates, int target) {
backtracking(candidates, target, 0, 0);
return res;
}
public void backtracking(int[] candidates, int target, int sum, int startIdx){
// 返回条件
if(sum > target){
return;
}
if(sum == target){
// 收集结果
res.add(new ArrayList<>(path));
}
// 深度递归
for(int i = startIdx; i < candidates.length; i++){
path.add(candidates[i]);
sum += candidates[i];
// 递归(这里的startIdx不会进行改变,是为了下一个深度继续使用之前的值)
backtracking(candidates, target, sum, i);
// 开始回溯
sum -= candidates[i];
path.removeLast();
}
}
}
总结
-
1、题目中的递归函数中参数的改变是我们要把握住的地方
- a:不能重复使用,startIdx就要+1
- b:可以重复使用还是使用原来的
-
2、重上一点,我们可以真正的理解到每一层树的每一个节点,我们是通过这个startIdx控制的从哪里开始
-
3、同时对for循环控制深度应该有了,跟深刻的理解,同时在每个深度点控制每个元素的多少