- 组合总和
给定一个无重复元素的数组 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合。
candidates 中的数字可以无限制重复被选取。
说明:
所有数字(包括 target)都是正整数。
解集不能包含重复的组合。
示例 1:
输入: candidates = [2,3,6,7], target = 7,
所求解集为:
[
[7],
[2,2,3]
]
示例 2:
输入: candidates = [2,3,5], target = 8,
所求解集为:
[
[2,2,2,2],
[2,3,3],
[3,5]
]
代码实现:
class Solution {
public:
vector<vector<int>> combinationSum(vector<int>& candidates, int target) {
vector<vector<int>> results;
vector<int> solution;
backtracking(candidates,target,0,solution,results);
return results;
}
void backtracking(vector<int> &candidates,int target,int start,vector<int>&solution,vector<vector<int>>&results){
if(target<0){//总和已经超出目标值(每添加一个新的目标,把它的值从总和中减去)
return;
}
if(target==0){//总和刚好等于目标值
results.push_back(solution);//把当前的子集添加到结果中
return;
}
for(int i=start;i<candidates.size();++i){//继续尝试把元素添加到当前的子集中
solution.push_back(candidates[i]);//添加了一个新的元素到方法子集中
backtracking(candidates,target-candidates[i],i,solution,results);//立即调用回溯函数看看是否找到了合适的子集
solution.pop_back();//递归完毕后,要把上次尝试的元素从子集里删除
}
}
};
另一个版本的代码实现:
class Solution {
public:
vector<vector<int>> combinationSum(vector<int>& candidates, int target) {
vector<vector<int>> res;
vector<int> tmp;
combinationSumCore(res,candidates,target,tmp,0,0);
return res;
}
void combinationSumCore(vector<vector<int>> &res,vector<int>& candidates,int target,vector<int>&tmp,int sum,int begin){
if(sum==target){
res.push_back(tmp);
}else{
for(int i=begin;i<candidates.size();++i){
if(sum+candidates[i]<=target){
tmp.push_back(candidates[i]);
combinationSumCore(res,candidates,target,tmp,sum+candidates[i],i);
tmp.pop_back();
}
}
}
}
};
疑点:
为何最后要弹出最新尝试的那个值?