错误解法一:每一次回溯都遍历提供的数组
class Solution {
public List<List<Integer>> combinationSum(int[] candidates, int target) {
List<List<Integer>> result = new ArrayList<List<Integer>>();
List<Integer> temp = new ArrayList<Integer>();
int sum = 0;
backtrack(candidates, target, result, temp, sum);
return result;
}
public void backtrack(int[] candidates, int target, List result, List temp, int sum){
if(sum==target){
result.add(temp);
}
for(int i=0; i<candidates.length; i++){
temp.add(candidates[i]);
backtrack(candidates, target, result, temp, sum-candidates[i]);
temp.remove(temp.size()-1);
}
}
}
错误原因:
- 没有回溯中止条件
- 未考虑到数字相同但是位置不同的情况,我们把这种情况也算作一次结果
解法一:(回溯法)每一次回溯尝试把第idx
个数加进去,考虑重复使用candidates[idx]
,或不使用candidates[idx]
(即:跳过)
class Solution {
public List<List<Integer>> combinationSum(int[] candidates, int target) {
List<List<Integer>> result = new ArrayList<List<Integer>>();
List<Integer> temp = new ArrayList<Integer>();
int idx = 0;
backtrack(candidates, target, result, temp, idx);
return result;
}
public void backtrack(int[] candidates, int target, List result, List temp, int idx){
if (idx == candidates.length) {
return;
}
if(target==0){
result.add(new ArrayList<Integer>(temp));
return;
}
if(target-candidates[idx]>=0){
temp.add(candidates[idx]);
backtrack(candidates, target-candidates[idx], result, temp, idx);
temp.remove(temp.size()-1);
}
backtrack(candidates, target, result, temp, idx+1);
}
}
注意:
- 这里要
new
,不能直接result.add(temp)
:result.add(new ArrayList<Integer>(temp))
- 结束标值:
temp
拿到所有candidate
- 找到和为
target
的序列