【Leetcode】组合总和

题目:

思路

1. 这是一道搜索和回溯的题目,首先要画出树形图,根据树的推理逻辑写代码;

2. 题目要求返回每个组合中元素的具体数值。需要在搜索过程中记录中间数值,采用深度优先搜索比较合适。

3. 题目要求组合不能重复,例如,[2,3,3],[3,2,3],[3,3,2]视为同一个组合。这里有一个trick可以在搜索过程中排除重复的组合:首先将候选数组排序,每次减去的数值都不能小于前一次减去的数值。这一步trick体现在函数searchDFS的参数start中。

class Solution {
public:
    vector<int> candidate;
    
    void searchDFS(int start, int target, vector<int>& path, vector<vector<int> >& res) {
        if(target == 0) {
            res.push_back(path);
            return;
        }
        
        if(target < candidate[start])  // 非常重要的判断条件
            return;
        
        for(int i = start; i < candidate.size(); ++i) {
            path.push_back(candidate[i]);
            searchDFS(i, target-candidate[i], path, res);
            path.pop_back();    // 非常巧妙的回溯操作
        }
            
    }
    
    vector<vector<int>> combinationSum(vector<int>& candidates, int target) {
        vector<int> caseVec;
        vector<vector<int> > result;

        sort(candidates.begin(), candidates.end());
        this->candidate = candidates;
        
        searchDFS(0, target, caseVec, result);  // 深度优先搜索,每找到一条完整路径就保存
        
        return result;
    }
};
执行用时 :8 ms, 在所有 cpp 提交中击败了99.81%的用户
内存消耗 :9.3 MB, 在所有 cpp 提交中击败了93.54%的用户
原文地址:https://www.cnblogs.com/gdut-gordon/p/9209082.html