回溯之Leetcode39——Combination Sum

本题大意就是在一个数字序列里找出相加和为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;
    }
};

点赞