本题的关键点在于组合中元素能够重合,那么在递归时,传入的 起始位置 就不必再加 1 ,但是也能不能没有起始位置,都从0开始。因为都从0开始,则会产生重复的结果。
递归的返回条件应当是 sum > target 或者 sum == target,在 sum == target时,将此时的 vec 添加到result数组中。
class Solution {
private:
vector<vector<int>> result;
vector<int> vec;
int sum = 0;
public:
void backtracking(vector<int> & candidates, int & target, int startIndex){
if(sum > target){
return;
}
if(sum == target){
result.push_back(vec);
return;
}
for(int i = startIndex; i < candidates.size(); i++){
sum += candidates[i];
vec.push_back(candidates[i]);
backtracking(candidates, target, i);
sum -= candidates[i];
vec.pop_back();
}
}
vector<vector<int>> combinationSum(vector<int>& candidates, int target) {
backtracking(candidates, target, 0);
return result;
}
};
剪枝操作首先对 candidates 进行了排序,然后 for 循环中添加了终止条件,减少递归的次数:
class Solution {
private:
vector<vector<int>> result;
vector<int> path;
void backtracking(vector<int>& candidates, int target, int sum, int startIndex) {
if (sum == target) {
result.push_back(path);
return;
}
// 如果 sum + candidates[i] > target 就终止遍历
for (int i = startIndex; i < candidates.size() && sum + candidates[i] <= target; i++) {
sum += candidates[i];
path.push_back(candidates[i]);
backtracking(candidates, target, sum, i);
sum -= candidates[i];
path.pop_back();
}
}
public:
vector<vector<int>> combinationSum(vector<int>& candidates, int target) {
result.clear();
path.clear();
sort(candidates.begin(), candidates.end()); // 需要排序
backtracking(candidates, target, 0, 0);
return result;
}
};