LeetCode39.40组合总和(dfs+回溯)

39.题目描述(来源LeetCode)

 思路:像这种求可行解的一般会想到要用回溯算法,回溯的过程记录可行解,不合适就回退一步,换一条道继续搜,继续回溯,对于每一个数,在每次搜索的时候有两种情况,加入可行解数组和不加入。搜索结束条件1.当加入可行解数组的和等于target的时候,2.当遍历完数组的时候

代码实现C++: 

class Solution {
public:
    vector<vector<int>> combinationSum(vector<int>& candidates, int target) {
        vector<int> num;//存放每一次回溯的可行解
        vector<vector<int>> res;//所有可行解
        sort(candidates.begin(),candidates.end());//注意,一定要是有序数组,不然在剪枝的过程会漏掉可行解
        dfsback(candidates,num,res,target,0);
        return res;
    }
    void dfsback(vector<int>& candidates,vector<int>& num,vector<vector<int>>& res,int target,int start){
        if(target==0){//当target==0说明该次搜索的可行解是ok的
            res.push_back(num);
            return;
        }
        for(int i=start;i<candidates.size();i++){//每次搜索从start开始,因为每一组可行解要是唯一的,如果每次都从0开始遍历+回溯,就会像排列组合一样,有许多重复的可行解
            if(target-candidates[i]>=0){
                num.push_back(candidates[i]);
                dfsback(candidates,num,res,target-candidates[i],i);//开始下一次搜索,还是从i开始,表示将该数继续加入可行解,如果不满足,在回溯的过程会将该数弹出,一般dfs+回溯的代码上下对称哦
                num.pop_back();
            }else{
                break;
            }
        }
    }
};

升级版: 40.无重复数字的可行解

 思路:无重复数字,意味着每个数字只有一种情况,加入或者不加入可行解,但是,我们要在先判断该数在数组里是否重复,有一个很好的办法就是排序,让每一个元素与前面一个元素比较是否相等就可以排除重复元素。

代码实现C++:

class Solution {
public:
        vector<vector<int>> res;//存最后的可行解组成的数组
        vector<int> num;//存每一次遍历的可行解
        vector<int> candidates;//数组
    vector<vector<int>> combinationSum2(vector<int>& candidates, int target) {
        sort(candidates.begin(),candidates.end());
        this->candidates=candidates;
        dfsback(0,target);//
        return res;
    }
    void dfsback(int start,int target){//start每次搜索的起始位置和target目标值
        if(target==0){
            res.push_back(num);
            return;
        }
        for(int i=start;i<candidates.size()&&target-candidates[i]>=0;i++){
            if(i>start&&candidates[i]==candidates[i-1]){//i>start是用来每次至少加入重复元素一个的,比如12224 在从第二个2开始遍历的时候,我们之加入一个2,但如果没有i>start限制,我们就无法加入当前的在原数组中有重复的元素了
                continue;
            }
            num.push_back(candidates[i]);
            dfsback(i+1,target-candidates[i]);//只有一种情况就是加入该元素并搜索下一个位置
            num.pop_back();
        }
    }
};

今日刷题任务完成啦~被回溯折磨的一天(欢迎大家在评论区交流哦!!)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值