Combination Sum
https://leetcode.com/problems/combination-sum/
题目中数值并不重复,而且允许使用多次,很简单的回溯算法,递归求解,注意先把数组排序一下,代码如下
class Solution {
public:
vector<vector<int> > combinationSum(vector<int>& candidates, int target) {
vector<vector<int> > ivv;
vector<int> tmp;
sort(candidates.begin(),candidates.end());
combinationSum2(ivv,candidates,tmp,target,0);
return ivv;
}
void combinationSum2(vector<vector<int> >& ivv,vector<int>& candidates, vector<int>& tmp,int target,int j) {
if(target<0)return ;
if(target==0){ivv.push_back(tmp);return ;}
for(int i=j;i<candidates.size();++i){
if(candidates[i]<=target){
tmp.push_back(candidates[i]);
combinationSum2(ivv,candidates,tmp,target-candidates[i],i);
tmp.pop_back();
}
}
}
};
Combination Sum2
https://leetcode.com/problems/combination-sum-ii/
题目中有数值的重复而只允许使用一次,因此需要排除重复数值,和上一题的思路一样,关键点在与排除重复的操作应该在递归之后,代码如下
class Solution {
public:
vector<vector<int> > combinationSum2(vector<int>& candidates,int target){
vector<vector<int> > ret;
vector<int> tmp;
sort(candidates.begin(),candidates.end());
helper(ret,tmp,candidates,target,0);
return ret;
}
void helper(vector<vector<int> >&ret,vector<int>& tmp,vector<int>& nums,int k,int j){
if(k<0) return ;
if(k==0){
ret.push_back(tmp);
return;
}
for(int i=j;i<nums.size();++i){
if(nums[i]<=k){
tmp.push_back(nums[i]);
helper(ret,tmp,nums,k-nums[i],i+1);
while(i<nums.size()&&nums[i]==nums[i+1]) {
i++;
}
tmp.pop_back();
}
}
}
};
Combination Sum3
https://leetcode.com/problems/combination-sum-iii/
题目给的数组为[1-9],区别于之前的题是增加了个数的限制,即k个不同的数构成n,求组合。思路一样,代码如下
class Solution {
public:
vector<vector<int>> combinationSum3(int k, int n) {
vector<vector<int>> result;
vector<int> path;
backtrack(result, path, 1, k, n);
return result;
}
void backtrack(vector<vector<int>> &result, vector<int> &path, int start, int k, int target){
if(target==0&&k==0){
result.push_back(path);
return;
}
for(int i=start;i<=10-k&&i<=target;i++){
path.push_back(i);
backtrack(result,path,i+1,k-1,target-i);
path.pop_back();
}
}//回溯,学习
};
Combination Sum4
https://leetcode.com/problems/combination-sum-iv/
题目给的提示是动态规划,公式dp[i]=Σdp[i-nums[k]] 0<=k<=nums.size()
代码如下
class Solution {
public:
int combinationSum4(vector<int>& nums, int target) {
vector<int> dp(target + 1);
dp[0] = 1;
sort(nums.begin(), nums.end());
for (int i = 1; i <= target; ++i) {
for (auto a : nums) {
if (i < a) break;
dp[i] += dp[i - a];
}
}
return dp.back();
}
};