题目描述:
Given a set of candidate numbers (C) (without duplicates) 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.
- 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] ]
找出数组中相加等于target的所有组合,并且不能重复,在数组中没有重复的值,但是在一个组合里面可以有重复的值。
这道题用递归的方法比较容易理解,每次递归传递的参数有当前已有的元素组合、当前的元素组合之和与target的差距,以及下一次递归在数组中查找元素的起始位置,同时在递归之前需要对数组排序,这两步都是为例避免重复所采取的方法,这样每次递归就可以不考虑之前已经遍历过的元素。如果当前查找的元素加上当前元素组合之和等于target,说明这是一个有效的组合,将其加入result数组中。如果当前元素加入后超过了target说明不能构成有效的组合,同时由于数组有序,所以之后的元素也不能构成有效的组合,在这种情况下,直接放弃接下来的递归。如果当前元素加入后小于target,说明还需要加入更多的元素才能构成有效的组合,那么同时由于组合允许重复的元素,所以start不变,但是target要相应的减小,然后继续递归。
class Solution {
public:
vector<vector<int>> combinationSum(vector<int>& candidates, int target) {
sort(candidates.begin(),candidates.end());
vector<vector<int> > result;
vector<int> cur;
combinationSum(candidates,target,result,cur,0);
return result;
}
void combinationSum(vector<int> candidates, int target,vector<vector<int> >& result,vector<int> cur,int start)
{
for(int i=start;i<candidates.size();i++)
{
vector<int> temp=cur;
if(candidates[i]<target)
{
temp.push_back(candidates[i]);
combinationSum(candidates,target-candidates[i],result,temp,i);
}
else if(candidates[i]==target)
{
temp.push_back(candidates[i]);
result.push_back(temp);
return;
}
else if(candidates[i]>target) break;
}
}
};
根据同理可以写出更清晰的代码,每次遍历的元素分加入和不加入两种情况递归,并在适当时候剪枝。
class Solution {
public:
vector<vector<int>> combinationSum(vector<int>& candidates, int target) {
vector<vector<int>> result;
vector<int> cur;
int i=0;
int sum=0;
sort(candidates.begin(),candidates.end());
DFS(candidates, target, i, sum, result, cur);
return result;
}
void DFS(vector<int>& candidates, int target, int i, int sum, vector<vector<int>>& result, vector<int> cur)
{
if((sum+candidates[i])>target||i>=candidates.size()) return;
else if((sum+candidates[i])==target)
{
cur.push_back(candidates[i]);
result.push_back(cur);
return;
}
else if((sum+candidates[i])<target)
{
DFS(candidates, target, i+1, sum, result, cur);
sum+=candidates[i];
cur.push_back(candidates[i]);
DFS(candidates, target, i, sum, result, cur);
return;
}
}
};