代码随想录刷题随记23-回溯3

代码随想录刷题随记23-回溯3

39. 组合总和

leetcode链接
注意同一个 数字可以 无限制重复被选取
怎么体现这个可以重复取的思想很重要
解题代码:

class Solution {
public:
    void backtrace( vector<vector<int>>& ret,vector<int> &path,vector<int>& candidates,int target,int index,int &sum){
        if(sum==target){
            ret.push_back(path);
            return ;
        }
        if(sum>target)
           return;
        for(int i=index;i<candidates.size();i++) {  
             path.push_back(candidates[i]);
             sum+=candidates[i];
             //重用
             backtrace(ret, path,candidates,target, i, sum);
             sum-=candidates[i];
             path.pop_back();
        }
    }
    vector<vector<int>> combinationSum(vector<int>& candidates, int target) {
        vector<vector<int>> ret;
        vector<int> path;
        int sum=0;
        backtrace(ret,path, candidates, target,  0, sum);
        return ret;
    }
};

40.组合总和II

leetcode链接
candidates 中的每个数字在每个组合中只能使用一次
同时因为candidite集合里面的数本来就有一样的,所以有肯能虽然取数顺寻不一致,但是结果集合相同的问题:
在这里插入图片描述

需要去重
去重的关键在于同一层不能重复,纵向上可以重复:
在这里插入图片描述
可以先对candidates进行排序,这样比较容易跳过
解题代码:

class Solution {
public:
    void backtrace( vector<vector<int>>& ret,vector<int>& candidates,int target,int sum,vector<int> & path,int index,vector<bool> &use){
        if(target==sum){
          ret.push_back(path);
          return;  
        }
       if(sum>target)
         return;
       for(int i=index;i<candidates.size();i++){  
            
            if(i>0&&candidates[i]==candidates[i-1]&&(use[i-1]==false)) 
               continue;  
           path.push_back(candidates[i]);
           
           sum+=candidates[i];
           use[i]=true;
           backtrace(ret,candidates,  target,  sum, path, i+1,use);
           sum-=candidates[i];
           use[i]=false;
           path.pop_back();
        }        

    }
    vector<vector<int>> combinationSum2(vector<int>& candidates, int target) {
       vector<vector<int>> ret;
       vector<int> path;
       int sum=0;
       std::sort(candidates.begin(),candidates.end());
       vector<bool> use(candidates.size(),false);
       backtrace(ret, candidates, target, sum,path, 0,use);
       return ret;
    }
};

131.分割回文串

leetcode链接

class Solution {
public:
    bool isstr(string str){
        if(str.size()==1)
          return true;
        int l=0;
        int r=str.size()-1;
        while(l<r){
            if(str[l]!=str[r])
            return false;
            l++;
            r--;
        }
        return true;
    }
    void backtrace( string s,vector<vector<string>>& ret,vector<string> &path,int curind,int lastind){
      if(curind==s.size()){
        ret.push_back(path);
        return;
      }
      string substring=s.substr(lastind,curind-lastind);
      //从当前切
      substring+=s[curind];
      if(isstr(substring)){
        path.push_back(substring);
        backtrace(s, ret, path,  curind+1, curind+1);
        path.pop_back();
      }
      substring.pop_back();
      //当前不切
      if(curind+1<s.size())
        backtrace(s, ret, path,  curind+1, lastind);
      
    }
    vector<vector<string>> partition(string s) {
       vector<vector<string>> ret;
       vector<string> path;
       backtrace(s, ret, path, 0, 0);
       return ret;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值