问题1:
给定一个无重复元素的数组 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合。
candidates 中的数字可以无限制重复被选取。
说明:
所有数字(包括 target)都是正整数。
解集不能包含重复的组合
class Solution {
public:
vector<vector<int>> res;
vector<vector<int>> combinationSum(vector<int>& candidates, int target) {
vector<int> tmp;
dfs(candidates,target,0,tmp);
return res;
}
void dfs(vector<int>& candidates,int target,int start,vector<int>& tmp){
if(target<0) return;
else if(target==0){
res.push_back(tmp);
return;
}
else{
for(int i=start;i<candidates.size();i++){
tmp.push_back(candidates[i]);
dfs(candidates,target-candidates[i],i,tmp);//start还是从i开始,因为可以重复选取
tmp.pop_back();
}
}
}
};
问题2:
给定一个数组 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合。
candidates 中的每个数字在每个组合中只能使用一次。
说明:
所有数字(包括目标数)都是正整数。
解集不能包含重复的组合。
与第一题的区别:
所给的数组中元素可能有重复,因此要去重
剪枝方法:
首先将数组排序,若递归的元素与前一个元素相等则不递归
class Solution {
public:
vector<vector<int>> res;
vector<vector<int>> combinationSum2(vector<int>& candidates, int target) {
sort(candidates.begin(),candidates.end());
vector<int> tmp;
dfs(candidates,target,0,tmp);
return res;
}
void dfs(vector<int>& candidates,int target,int start,vector<int>& tmp){
if(target<0) return;
else if(target==0){
res.push_back(tmp);
return;
}
else{
for(int i=start;i<candidates.size();i++){
if(i>start&&candidates[i]==candidates[i-1]) continue;
tmp.push_back(candidates[i]);
dfs(candidates,target-candidates[i],i+1,tmp);
tmp.pop_back();
}
}
}
};
问题3:
找出所有相加之和为 n 的 k 个数的组合。组合中只允许含有 1 - 9 的正整数,并且每种组合中不存在重复的数字。
说明:
所有数字都是正整数。
解集不能包含重复的组合。
与问题1、2相似,增加一个变量Level来控制递归的层数
class Solution {
public:
vector<vector<int>> res;
vector<vector<int>> combinationSum3(int k, int n) {
vector<int>tmp;
dfs(n,k,0,1,tmp);
return res;
}
void dfs(int target,int level,int num,int start,vector<int>&tmp){
if(target==0&&num==level){
res.push_back(tmp);
return;
}
if(num<level&&target>0){
for(int i=start;i<=9;i++){
tmp.push_back(i);
dfs(target-i,level,num+1,i+1,tmp);
tmp.pop_back();
}
}
}
};
问题4:
给定两个整数 n 和 k,返回 1 … n 中所有可能的 k 个数的组合。
增加一个变量Level来控制递归的层数
class Solution {
public:
vector<vector<int>> res;
vector<vector<int>> combine(int n, int k) {
vector<int> tmp;
dfs(n,k,0,1,tmp);
return res;
}
void dfs(int n,int k,int level,int start,vector<int>& tmp){
if(level==k){
res.push_back(tmp);
return;
}
for(int i=start;i<=n;i++){
tmp.push_back(i);
dfs(n,k,level+1,i+1,tmp);
tmp.pop_back();
}
}
};