随想录训练营23/60 | LC 39. 组合总和;LC 40.组合总和II;LC 131.分割回文串

LC 39. 组合总和

题目链接 LC 39. 组合总和
思路:每个数字可以被无限选取,但是不能有重复的组合,那么递归的时候每次从包括目前正在递归的值开始遍历,也没有深度要求,那么当sum大于taget时就return,当sum==target就保存,当sum<target时就继续递归。
代码

class Solution {
public:
    vector<vector<int>> result;
    vector<int> path;
    void backtracking(int sum, int target, int begin, vector<int>& candidates){
        if(sum==target){//当总和等于目标值,就保存结果,并且返回
            result.push_back(path);
            return;
        }
        if(sum>target){//当总和大于目标值,就直接返回
            return;
        }
        //当目标值小于总和,就进行递归
        for(int i=begin; i<candidates.size(); i++){
            path.push_back(candidates[i]);
            sum = sum+candidates[i];
            backtracking(sum, target, i, candidates);//注意也是从第i个开始,因为同一个数可以去无数次
            sum = sum-candidates[i];
            path.pop_back();
        }
    }
    vector<vector<int>> combinationSum(vector<int>& candidates, int target) {
        backtracking(0, target, 0, candidates);
        return result;
    }
};

LC 40.组合总和II

题目链接LC 40.组合总和II
思路:递归法,每次将集合中的一个元素放到临时vector中,判断vector中的值是否满足要求,若满足要求就保存vector,并且返回;若不满足要求就继续递归,但递归的集合中没有刚进入vector的元素。注意,题干要求不能有重复解;当一个元素在集合中多次出现时,可以同时使用相同的元素进行组合,但是不能有重复的去重的思路为:对其进行排序,当一个元素递归完后,若后面一个元素与其相同,那么后面的元素就不用递归了,在二叉树中显示的就是同一层中不能有相同的元素。
代码

class Solution {
public:
    vector<vector<int>> result;
    vector<int> path;
    void backtracking(int sum, int target, int begin, vector<int>& candidates){
        if(sum==target){
            result.push_back(path);
            return;
        }
        if(sum>target){
            return;
        }
        for(int i=begin; i<candidates.size(); i++){
            sum = sum + candidates[i];
            path.push_back(candidates[i]);
            backtracking(sum, target, i+1, candidates);
            sum = sum - candidates[i];
            path.pop_back();
            //去重
            while(i+1<candidates.size() && candidates[i+1]==candidates[i]){
                i++;
            }
        }
    }
    vector<vector<int>> combinationSum2(vector<int>& candidates, int target) {
        //对candidates进行排序
        sort(candidates.begin(), candidates.end());
        backtracking(0, target, 0, candidates);
        return result;
    }
};

LC 131.分割回文串

题目链接LC 131.分割回文串
思路:将字符串分割成子串,每个子串满足回文子串的要求。先取第一个字符判断是不是回文子串,若是就取后面的一个字符,一直往后;若该字串不为回文字串就将其后面一个字符加入字串中,直到字符串末尾。
代码

class Solution {
public:
    vector<vector<string>> result;
    vector<string> path;
    //判断s是否是回文子串
    bool isPalindrome(string s){
        for(int i=0, j=s.size()-1; i<s.size(), j>=0;i++, j--){
            if(s[i]!=s[j]){
                return false;
            }
        }
        return true;
    }
    void backtracking(int begin, string s){
        if(begin==s.size()){//当遍历到s末尾就结束
            result.push_back(path);
            return;
        }
        for(int i=begin; i<s.size(); i++){
            //取从开始到i的字串
            string tmp = s.substr(begin, i-begin+1);
            //若字串为回文字串就将字串放入result中,并递归
            if(isPalindrome(tmp)){
                path.push_back(tmp);
                backtracking(i+1, s);
                path.pop_back();
            }
            //若不是回文字串就进行下次循环
        }
    }

    vector<vector<string>> partition(string s) {
        result.clear();
        path.clear();
        backtracking(0, s);
        return result;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值