题目:
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.
给出一组候选数字C和一个目标数字T,在C中找出不同的连接使得候选数字的和为T。C中的数字可以使用多次。
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]
思路:
典型的DFS,注意题目要求数字可以重复使用,因此dfs的for循环里的下次开始深搜的开始点是从当前位置开始。具体实现看代码。
代码:
class Solution {
public:
vector<vector<int> > combinationSum(vector<int> &candidates, int target)
{
vector<vector<int> > result;
vector<int> path;
if(candidates.empty())
return result;
sort(candidates.begin(),candidates.end());//对candidates排序保证combination是有序的
dfs(candidates,result,path,0,target);
return result;
}
//利用target减去当前数字,最后减到0说明找到符合条件的combination
void dfs(vector<int> &candidates,vector<vector<int> > &result,vector<int> &path,int start,int gap)
{
//gap为0,说明找到符合的条件
if(gap == 0)
{
result.push_back(path);
return;
}
for(int i = start ; i < candidates.size() ; i++)
{
//如果gap小于当前值,则结束当前遍历,因为i之后的数更大不会有符合条件的结果
if(gap < candidates[i])
return;
//否则把当前数字push进path
path.push_back(candidates[i]);
dfs(candidates,result,path,i,gap-candidates[i]);//对数组剩下的数字继续递归,注意这里的i,是从当前数字继续遍历,因为题目允许一个数字使用多次
path.pop_back();
}
}
};
下面的方法和上面的并无差别,只是求差变成求和:
class Solution {
public:
vector<vector<int> > combinationSum(vector<int> &candidates, int target)
{
vector<vector<int> > result;
vector<int> path;
if(candidates.empty())
return result;
sort(candidates.begin(),candidates.end());//对candidates排序保证combination是有序的
dfs(candidates,result,path,0,0,target);
return result;
}
//利用数字累加,直到最后等于target,即找到符合条件的combination
void dfs(vector<int> &candidates,vector<vector<int> > &result,vector<int> &path,int start,int cur,int target)
{
if(cur == target)
{
result.push_back(path);
return;
}
for(int i = start ; i < candidates.size() ; i++)
{
//如果cur大于target,则结束当前遍历
if(cur > target)
return;
//否则把当前数字push进path
path.push_back(candidates[i]);
dfs(candidates,result,path,i,cur+candidates[i],target);//对数组剩下的数字继续递归,注意这里的i,是从当前数字继续遍历,因为题目允许一个数字使用多次
path.pop_back();
}
}
};
本题疑问:按上面的代码如果原数组有重复的数字的话,结果应该是有重复的combination的,但是还是AC了,不懂?