我对此回溯解决方案的分析是否正确?

时间:2018-01-05 17:49:01

标签: c++ recursion backtracking recursive-backtracking

我正在尝试在LeetCode.com上解决以下问题:

  

给定一组候选数字(C)(没有重复)和目标数字(T),找到C中所有唯一的组合,其中候选数字总和为T.

     

可以从C无限次数中选择相同的重复数字。   因此,如果输入为[2, 3, 6, 7]且目标为7,则输出应为:

     

[
   [7],
   [2,2,3]
  ]

高度赞成的解决方案是这样的:

class Solution {
public:    
    vector<vector<int>> combinationSum(vector<int>& candidates, int target) {
        vector<vector<int>> result;
        vector<int> res;

        combinationSumUtil(result, candidates, res, target, 0);
        return result;
    }

    void combinationSumUtil(vector<vector<int>>& result, vector<int>& candidates, vector<int>& res, int target, int start) {
        int sum=0;
        for(auto each: res) sum+=each;
        if(sum==target) {
            result.push_back(res);
            return;
        }
        if(sum>target) return;

        for(int i=start; i<candidates.size(); i++) {
            res.push_back(candidates[i]);
            combinationSumUtil(result, candidates, res, target, i);
            res.pop_back();
        }
    }
};

经过调试并试图了解到底发生了什么,我理解了以下内容:

  • 该代码段如何包含相同数字两次或更多次(如[2, 2, 3]中所述) - 再次使用i(而不是i+1,通过{{ 1}}变量)。
  • 如何通过使用start变量确保多次不包含相同的集合(例如[2, 2, 3][2, 3, 2])。使用这个变量,我们基本上是前进。假设输入为start。现在,当我们遇到[3,2,6,7]时,我们之前已经遇到过2。因此,当我们访问3时,我们无法再次遇到(上一个)2来形成集合3。在每次迭代中,我们只能遇到当前的那个或后来的那个 - 从来没有遇到过前一个(并且输入只有不同的元素)。如果没有[2, 3, 2]变量,归纳变量start可能会在每次递归调用中从i开始(因此,我们也会遇到以前的值(例如0} ,当我们当前在3时导致重复集合。)

我的问题很简单 - 我的理解正确

1 个答案:

答案 0 :(得分:0)

您的理解是正确的,它会通过再次尝试2而不是2之前的任何数字来找到类似2,2,3的情况。

我想说更多“c ++”类型的答案会使用迭代器范围而不是制作向量的副本,并且每个递归调用都会在必要时使用递增的启动迭代器位置。这样的解决方案只是从C.cbegin(),C.cend()开始,并采用前面的总参数而不是'start'。

这样,如果C为3,5,10和T为10,它会尝试组合使用3开始并找不到匹配然后继续到从5开始的组合并再次尝试集合5,10与前面的总数'5',此时5,5将匹配。