C++ 组合和

C++ 组合和,c++,recursion,combinations,backtracking,C++,Recursion,Combinations,Backtracking,给定一组候选数(C)和一个目标数(T),找出C中候选数和T之和的所有唯一组合 相同的重复次数可从C中选择,次数不限 例如, 给定候选集2,3,6,7和目标7, 解决方案集是: [2,2,3] [7] 解决方案代码为: class Solution { public: void doWork(vector<int> &candidates, int index, vector<int> &current, int currentSum,

给定一组候选数(C)和一个目标数(T),找出C中候选数和T之和的所有唯一组合

相同的重复次数可从C中选择,次数不限

例如, 给定候选集
2,3,6,7
和目标
7
, 解决方案集是:

[2,2,3]
[7] 

解决方案代码为:

class Solution {
    public:

    void doWork(vector<int> &candidates, int index, vector<int> &current, int currentSum, int target, vector<vector<int> > &ans) {
        if (currentSum > target) {
            return;
        }
        if (currentSum == target) {
            ans.push_back(current);
            return;
        }
        for (int i = index; i < candidates.size(); i++) {
            current.push_back(candidates[i]);
            currentSum += candidates[i];

            doWork(candidates, i, current, currentSum, target, ans);

            current.pop_back();
            currentSum -= candidates[i];
        }

    }

    vector<vector<int>> combinationSum(vector<int> &candidates, int target) {
        vector<int> current; 
        vector<vector<int> > ans;
        sort(candidates.begin(), candidates.end());
        vector<int> uniqueCandidates;
        for (int i = 0; i < candidates.size(); i++) {
            if (i == 0 || candidates[i] != candidates[i-1]) {
                uniqueCandidates.push_back(candidates[i]);
            }
        }
        doWork(uniqueCandidates, 0, current, 0, target, ans); 
        return ans;
    }
};
类解决方案{
公众:
无效工作(向量和候选项、整数索引、向量和当前、整数当前和、整数目标、向量和ans){
如果(currentSum>目标){
返回;
}
如果(currentSum==目标){
ans.推回(当前);
返回;
}
for(int i=index;i
现在,虽然我可以通过一个例子来理解这个解决方案,但我自己怎么能得出这样的解决方案呢。此功能的主要工作如下:

    for (int i = index; i < candidates.size(); i++) {
        current.push_back(candidates[i]);
        currentSum += candidates[i];

        doWork(candidates, i, current, currentSum, target, ans);

        current.pop_back();
        currentSum -= candidates[i];
    }
for(int i=index;i

请告诉我如何理解上述代码以及如何思考解决方案。我可以解决基本的递归问题,但这些问题看起来遥不可及。感谢您的时间。

因此,代码的基本功能是:

  • 按递增顺序对给定的数字集进行排序
  • 从集合中删除重复项
  • 对于集合中的每个数字:
    • 继续添加相同的数字,直到总和大于或等于目标值
    • 如果相等,则保存组合
    • 如果较大,则删除最后添加的数字(返回上一步),并开始将集合中的下一个数字添加到总和
  • 为了理解递归,我喜欢从非常简单的案例开始。让我们来看一个例子:
    候选人:{2,2,1}
    目标:4

    排序和删除重复项会将集合更改为{1,2}。递归的顺序为:

    • 总和=1;
      • 总和=1+1;
        • 总和=1+1+1;
          • 总和=1+1+1+1;(与目标相同,保存组合)
          • 总和=1+1+1+2;(大于目标,无需添加更多数字)
        • 总和=1+1+2;(保存组合,无需添加更多数字)
      • 总和=1+2;
        • 总和=1+2+2;(大一点,没有更多的数字)
    • 总和=2;
      • 总和=2+2;(保存,这是最后一次递归)

    为什么我会被否决?你很可能会被否决,因为人们觉得你是在要求别人为你做工作,而不是在你已经试图解决的问题上寻求帮助。@MikelF我至少花了6个小时来解决这个问题。我不知道“尝试”的定义是什么?请理解我并不是说你没有试图解决问题。我想说的是,人们可能认为你在要求别人免费编码。谢谢,但你也能告诉我如何使用递归函数吗。我的意思是,我的思考过程应该是循序渐进的,很抱歉太天真了。非常感谢。我现在明白了。
        for (int i = index; i < candidates.size(); i++) {
            current.push_back(candidates[i]);
            currentSum += candidates[i];
    
            doWork(candidates, i, current, currentSum, target, ans);
    
            current.pop_back();
            currentSum -= candidates[i];
        }