【C++、回溯】LeetCode39. 组合总和

该博客介绍了如何使用C++和回溯算法解决LeetCode39题——组合总和问题。题目要求找到数组中所有可能的组合,使得它们的和等于目标数,允许重复选取数组中的元素。博客提供了两种不同的代码实现,并提出了一个关于回溯过程中的疑问:为何需要在结束时移除最后一个尝试的值。
摘要由CSDN通过智能技术生成
  1. 组合总和

给定一个无重复元素的数组 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合。

candidates 中的数字可以无限制重复被选取。

说明:

所有数字(包括 target)都是正整数。
解集不能包含重复的组合。

示例 1:

输入: candidates = [2,3,6,7], target = 7,
所求解集为:
[
  [7],
  [2,2,3]
]

示例 2:

输入: candidates = [2,3,5], target = 8,
所求解集为:
[
  [2,2,2,2],
  [2,3,3],
  [3,5]
]

代码实现:

class Solution {
public:
    vector<vector<int>> combinationSum(vector<int>& candidates, int target) {
        vector<vector<int>> results;
        vector<int> solution;
        backtracking(candidates,target,0,solution,results);
        return results;
    }

    void backtracking(vector<int> &candidates,int target,int start,vector<int>&solution,vector<vector<int>>&results){
        if(target<0){//总和已经超出目标值(每添加一个新的目标,把它的值从总和中减去)
            return;
        }
        if(target==0){//总和刚好等于目标值
            results.push_back(solution);//把当前的子集添加到结果中
            return;
        }
        for(int i=start;i<candidates.size();++i){//继续尝试把元素添加到当前的子集中
            solution.push_back(candidates[i]);//添加了一个新的元素到方法子集中
            backtracking(candidates,target-candidates[i],i,solution,results);//立即调用回溯函数看看是否找到了合适的子集
            solution.pop_back();//递归完毕后,要把上次尝试的元素从子集里删除
        }
    }
};

另一个版本的代码实现:

class Solution {
public:
    vector<vector<int>> combinationSum(vector<int>& candidates, int target) {
        vector<vector<int>> res;
        vector<int> tmp;
        combinationSumCore(res,candidates,target,tmp,0,0);
        return res;
    }

    void combinationSumCore(vector<vector<int>> &res,vector<int>& candidates,int target,vector<int>&tmp,int sum,int begin){
        if(sum==target){
            res.push_back(tmp);
        }else{
            for(int i=begin;i<candidates.size();++i){
                if(sum+candidates[i]<=target){
                    tmp.push_back(candidates[i]);
                    combinationSumCore(res,candidates,target,tmp,sum+candidates[i],i);
                    tmp.pop_back();
                }
            }
        }
    }
};

疑点:
为何最后要弹出最新尝试的那个值?

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值