您的位置:首页 > 其它

LeetCode题解——Combination Sum

2015-08-25 21:16 387 查看
Given a set of candidate numbers (C) and a target number (T), find all unique combinations in C where
the candidate numbers sums to T.
The same repeated number may be chosen from C unlimited number of times.
Note:

All numbers (including target) will be positive integers.
Elements in a combination (a1, a2,
… , ak) must be in non-descending order. (ie, a1 ≤ a2 ≤
… ≤ ak).
The solution set must not contain duplicate combinations.

For example, given candidate set
2,3,6,7
and
target
7
,

A solution set is:

[7]


[2, 2, 3]


Hide Tags
Array Backtracking

Hide Similar Problems
(M) Letter Combinations of a Phone Number (M)
Combination Sum II (M) Combinations (M)
Combination Sum III (M) Factor Combinations

首先将candidates排好序
第一种方法:递归,对于每个candidate[i]有三种情况:
(1)等于target,则candidate[i]是一种组合,加入res中,返回
(2)小于target,则判断candidate[i]与前面的数能否组成target,即递归调用 combinationSum(temp,target-candidates[i]*m);
(3)大于target, 则直接返回
class Solution {//递归36ms
public:
vector<vector<int>> combinationSum(vector<int>& candidates, int target) {
vector<vector<int>> ans;
sort(candidates.begin(),candidates.end());
if(candidates.size()==0) return ans;
else if(candidates[0]>target) return ans;
else if(candidates[0]==target) {
vector<int> t; t.push_back(target);
ans.push_back(t);
return ans;
}

int N = candidates.size();

for(int i=0; i<N; i++ )
{
if(candidates[i]==target)
{
vector<int> t;
t.push_back(target);
ans.push_back(t);
break;
}
else if(candidates[i]<target)//看看前面能不能组合成target
{
vector<int> temp;
if(target%candidates[i]==0)
{
for(int m=0; m<target/candidates[i]; m++)
{
temp.push_back(candidates[i]);
}
ans.push_back(temp);
}

temp.assign(candidates.begin(),candidates.begin()+i);
for(int m=1; m<=target/candidates[i]; m++)
{
vector<vector<int>> t;
t=combinationSum(temp,target-candidates[i]*m);
if(t.size())
{
for(int j=0;j<t.size();j++)
{
for(int l=0;l<m;l++)
{
t[j].push_back(candidates[i]);
}
ans.push_back(t[j]);
}
}
}

}
}
return ans;
}
};


第二种方法,DP
combinations[i] 表示组成i的组合,我们最终需要求得conbinations[target];
那么动态数组的大小为target+1,combinations[0]到combinations[target],依次求出
class Solution {//DP54ms
public:
vector<vector<int> > combinationSum(vector<int> &candidates, int target) {
sort(candidates.begin(), candidates.end());
vector< vector< vector<int> > > combinations(target + 1, vector<vector<int>>());
combinations[0].push_back(vector<int>());
for (auto& score : candidates)
for (int j = score; j <= target; j++){
auto sls = combinations[j - score];
if (sls.size() > 0) {
for (auto& s : sls)
s.push_back(score);
combinations[j].insert(combinations[j].end(), sls.begin(), sls.end());
}
}
return combinations[target];
}
};


第三种方法,递归,16ms,与第一种方法类似,但是省略了更多的错误组合的判断
class Solution {//递归16ms
public:
vector<vector<int> > combinationSum(vector<int> &candidates, int target) {
sort(candidates.begin(), candidates.end());
vector<vector<int> > res;
vector<int> combination;
combinationSum(candidates, target, res, combination, 0);//递归,找到和为target的所有组合
return res;
}
private:
void combinationSum(vector<int> &candidates, int target, vector<vector<int> > &res, vector<int> &combination, int begin) {
if  (!target) {
res.push_back(combination);
return;
}
for (int i = begin; i != candidates.size() && target >= candidates[i]; ++i) {//每循环一次结束,combination置0
combination.push_back(candidates[i]);
combinationSum(candidates, target - candidates[i], res, combination, i);
combination.pop_back();
}
}
};
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: