7.39. 组合总和

思路:

同样回溯模板题

储备:

代码随想录

问题重点:

1、注意剪枝的位置的区别。

2、先写循环体,再去补充你要写的那些东西。按照你的思路来。

递归的参数也可以后面慢慢加。需要了再加。

3、

此外还定义了int型的sum变量来统计单一结果path里的总和,其实这个sum也可以不用,用target做相应的减法就可以了,最后如何target==0就说明找到符合的结果了,但为了代码逻辑清晰,依然用了sum。

最后:

放在for循环剪枝,避免进入多一层递归。需要提前排序一下:

class Solution {
public:

    vector<vector<int>> res;
    vector<int> path;
    int sum=0;
    void trace(vector<int>& candidates, int target, int idx, int sum) {
        // if (sum>target) return ;//剪枝.也可以放在for循环里面剪

        if (sum==target) {
            res.push_back(path);
            return ;
        }

        for (int i=idx;i<candidates.size() && sum+candidates[i]<=target;i++) {
            sum+=candidates[i];
            path.push_back(candidates[i]);
            trace(candidates,target,i,sum); //可以重复读取,不用+1.每层递归把上一层的排除在集合之外
            sum-=candidates[i];
            path.pop_back();
        }
        return ;
    }

    vector<vector<int>> combinationSum(vector<int>& candidates, int target) {
        sort(candidates.begin(),candidates.end());//放在for循环里剪枝需要排序
        trace(candidates, target, 0, sum);
        return res;
    }
};

放在外面剪枝:

class Solution {
    public:
    
        vector<vector<int>> res;
        vector<int> path;
        int sum=0;
        void trace(vector<int>& candidates, int target, int idx, int sum) {
            if (sum>target) return ;//剪枝.也可以放在for循环里面剪跳过递归更优化
    
            if (sum==target) {
                res.push_back(path);
                return ;
            }
    
            for (int i=idx;i<candidates.size();i++) {
                sum+=candidates[i];
                path.push_back(candidates[i]);
                trace(candidates,target,i,sum); //可以重复读取,不用+1.每层递归把上一层的排除在集合之外
                path.pop_back();
                sum-=candidates[i];
            }
            return ;
        }
    
        vector<vector<int>> combinationSum(vector<int>& candidates, int target) {
            trace(candidates, target, 0, sum);
            return res;
        }
    };

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值