题目
给定一个无重复元素的数组 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合。
candidates 中的数字可以无限制重复被选取。
算法
找到解答树,然后达到目标后回溯,最终通过排序剪枝达到优化算法的目的
代码时递归的模板代码
- 给出边界条件
- 递归
- 最终回溯
代码
class Solution {
private:
vector<vector<int>>ans;
vector<int> cur;
int sum,target,n ;
public:
vector<vector<int>> combinationSum(vector<int>& candidates, int target) {
this->target=target;
n=candidates.size();
sum=0;
sort(candidates.begin(),candidates.end());
DFS(0,candidates);
return ans;
}
void DFS(int start,vector<int>& nums){
if(sum==target){
ans.push_back(cur);
return;
}
for(int i=start;i<n&&sum+nums[i]<=target;i++){
sum+=nums[i];
cur.push_back(nums[i]);
DFS(i,nums);
sum-=nums[i];
cur.pop_back();
}
}
};
提升
candidates 中的每个数字在每个组合中只能使用一次。
代码
class Solution {
private:
vector<vector<int>>ans;
vector<int> cur;
int sum,target,n ;
public:
vector<vector<int>> combinationSum2(vector<int>& candidates, int target) {
this->target=target;
n=candidates.size();
sum=0;
sort(candidates.begin(),candidates.end());
DFS(0,candidates);
return ans;
}
void DFS(int start,vector<int>& nums){
if(sum==target){
ans.push_back(cur);
return;
}
for(int i=start;i<n&&sum+nums[i]<=target;i++){
sum+=nums[i];
cur.push_back(nums[i]);
DFS(i+1,nums);
sum-=nums[i];
cur.pop_back();
while(i+1<n&&nums[i+1]==nums[i])
i++;
}
}
};