主要思路:
与前面思路差不多,唯一的区别就是因为允许有重复元素所以递归结束条件为sum > target与sum == target,而且startIndex每次也不用递增1
代码实现:
class Solution {
public:
vector<vector<int>>ans;
vector<int>path;
void backtracking(vector<int>& candidates, int target, int sum, int startIndex) {
if(sum > target) return;
if(sum == target) {
ans.push_back(path);
return;
}
for(int i = startIndex; i < candidates.size(); i++) {
//printf("%d\n", candidates[i]);
sum += candidates[i];
path.push_back(candidates[i]);
backtracking(candidates, target, sum, i);
sum -= candidates[i];
path.pop_back();
}
}
vector<vector<int>> combinationSum(vector<int>& candidates, int target) {
backtracking(candidates, target, 0, 0);
return ans;
}
};
剪枝优化:
对原数组排序后,如果当前层的往下递归,加上第一个(最小)已经 > target,那就没必要递归之后的
class Solution {
public:
vector<vector<int>>ans;
vector<int>path;
void backtracking(vector<int>& candidates, int target, int sum, int startIndex) {
if(sum > target) return;
if(sum == target) {
ans.push_back(path);
return;
}
for(int i = startIndex; i < candidates.size() && sum + candidates[i] <= target; i++) {
//printf("%d\n", candidates[i]);
sum += candidates[i];
path.push_back(candidates[i]);
backtracking(candidates, target, sum, i);
sum -= candidates[i];
path.pop_back();
}
}
vector<vector<int>> combinationSum(vector<int>& candidates, int target) {
sort(candidates.begin(), candidates.end());
backtracking(candidates, target, 0, 0);
return ans;
}
};
主要思路:
关键在去重
同一起点(树枝)递归:不用去重
不同起点(树层)递归:要去重,因为如果前面有重复元素,前面肯定就已经遍历过现在可能的情况了
易错点:
要先对原数组排序
代码实现:
class Solution {
public:
vector<vector<int>>result;
vector<int>path;
void backtracking(vector<int>& candidates, int target, int startIndex, int sum) {
if(sum > target) return;
if(sum == target) {
result.push_back(path);
return;
}
for(int i = startIndex; i < candidates.size(); i++) {
// printf("%d\n",candidates[i]);
//用startIndex就可以替代used数组的作用,因为i > startIndex就说明在同一层
if(i > startIndex && candidates[i] == candidates[i - 1]) continue;
// printf("%d\n",candidates[i]);
sum += candidates[i];
path.push_back(candidates[i]);
backtracking(candidates, target, i + 1, sum);
sum -= candidates[i];
path.pop_back();
}
}
vector<vector<int>> combinationSum2(vector<int>& candidates, int target) {
sort(candidates.begin(), candidates.end());
backtracking(candidates, target, 0, 0);
return result;
}
};