本题大意就是在一个数字序列里找出相加和为target的几个数,序列的每个数可以重复使用
For example, given candidate set [2, 3, 6, 7]
and target 7
,
A solution set is:
[ [7], [2, 2, 3] ]
这道题我们依然使用回溯法解决问题,要求我们枚举嘛~~~我们先给待查找数组排序(后面我会说明排序的原因)
我们设一个tag表示那个target,每加一个一个数,就从tag里减掉这个数,直到tag==0说明找到一种解,这就是递归终止的条件。
if(!tag){ans.push_back(a);return;}
这道题使用循环递归,即在递归里套一个for循环。(ps.LeetCode上很多题都是循环递归)。我们用一个index标记我们搜到哪一个元素。接下来就是套路啦。一个for循环,从当前位置的元素起始:如果这个元素大于tag,说明多了,不能使用这个元素,直接可以return了,为什么可以直接return而不是continue就是因为我们已经排好序,后面肯定也是大于tag。
如果不大于tag,进递归,但是要注意题目要求每个元素可以重复使用,所以这里往下一层递归的index仍然是这个元素的索引,而不是下一个元素的索引
最后不要忘了回溯,把刚加进的元素pop出来.
for(int i=index;i<c.size();i++){
if(c[i]>tag)return;
a.push_back(c[i]);
dfs(tag-c[i],c,a,ans,i);
a.pop_back();
}
一个完整的dfs就写了出来!
详见AC代码:
class Solution {
public:
vector<vector<int>> combinationSum(vector<int>& candidates, int target) {
vector <int> a;
vector <vector <int>> ans;
sort(candidates.begin(),candidates.end());
dfs(target,candidates,a,ans,0);
return ans;
}
void dfs(int tag,vector <int> &c,vector <int> &a,vector <vector <int>> &ans,int index)
{
if(!tag){ans.push_back(a);return;}
for(int i=index;i<c.size();i++){
if(c[i]>tag)return;
a.push_back(c[i]);
dfs(tag-c[i],c,a,ans,i);
a.pop_back();
}
return;
}
};