解法:回溯算法
class Solution {
public:
vector<vector<int>> res; //返回值
void backtrack(vector<int>& track,vector<int>& candidates,int target,int beg){
//满足条件返回
if(target==0){
if(find(res.begin(),res.end(),track)==res.end()) //去除重复组合
res.push_back(track);
return;
}
if(target<0) return;
for(int i=beg;i<candidates.size();i++){
track.push_back(candidates[i]);
backtrack(track,candidates,target-candidates[i],i+1);
track.pop_back();
}
}
vector<vector<int>> combinationSum2(vector<int>& candidates, int target) {
sort(candidates.begin(),candidates.end()); //有重复数字为避免顺序不同的重复组合 先排序
vector<int> track; //路径
backtrack(track,candidates,target,0);
return res;
}
};
方法二
class Solution {
public:
vector<vector<int>> res; //返回值
void backtrack(vector<int>& track,vector<int>& candidates,int target,int start,vector<int>& used){
if(target==0){ //满足条件返回
res.push_back(track);
return;
}
if(target<0) return; //枝剪
for(int i=start;i<candidates.size();i++){
if(i>start && !used[i-1] && candidates[i]==candidates[i-1]) //枝剪:和上一个相同且上一个没使用过
continue;
track.push_back(candidates[i]);
used[i]=true;
backtrack(track,candidates,target-candidates[i],i+1,used);
track.pop_back();
used[i]=false;
}
}
vector<vector<int>> combinationSum2(vector<int>& candidates, int target) {
sort(candidates.begin(),candidates.end()); //有重复数字为避免顺序不同的重复组合 先排序
vector<int> used(candidates.size(),false); //使用标记
vector<int> track; //路径
backtrack(track,candidates,target,0,used);
return res;
}
};