class Solution {
List<List<Integer>> res = new ArrayList<>();
List<Integer>path= new ArrayList<>();
public List<List<Integer>> combinationSum(int[] candidates, int target) {
backtrack(candidates,target,0,0);
return res;
}
public void backtrack(int[] candidates,int target,int count,int start){
if(count==target){
res.add(new ArrayList<>(path));
return;
}
if(count>target) return;
for(int i=start;i<candidates.length;i++){
path.add(candidates[i]);
backtrack(candidates,target,count+candidates[i],i);
path.remove(path.size()-1);
}
}
}
- 2.3
- 想难了,回溯的特性就是会重复遍历每一种情况,所以在回溯参数中加入 sum 参数和 start 参数(控制不回头,以去重【2,3】和【3,2】这种重复情况)
- 11.21
- 回溯函数需要有一个sum参数和start参数
- 感觉比前三个简单
class Solution {
List<List<Integer>> res = new ArrayList<>();
List<Integer> path = new ArrayList<>();
public List<List<Integer>> combinationSum(int[] candidates, int target) {
backtrack(candidates,target,0,0);
return res;
}
public void backtrack(int[] nums,int target,int sum,int start){
if(sum==target){
res.add(new ArrayList<>(path));
return;
}
if(sum>target) return;
for(int i=start; i<nums.length;i++){
path.add(nums[i]);
backtrack(nums,target,sum+nums[i],i);//i,不是i+1,可以被重复使用
path.remove(path.size()-1);
}
}
}
- 这里要注意加一个开始标记和总和标记
- 退出条件为相等
- 注意sum>target时进行剪枝
- 可以被重复使用
- test