当前位置:   article > 正文

代码随想录算法训练营第二十七天|39. 组合总和、40.组合总和II、131.分割回文串

代码随想录算法训练营第二十七天|39. 组合总和、40.组合总和II、131.分割回文串

回溯


一、组合总和

和之前的组合思路类似,差别在于允许重复,所以startIndex进入下一递归时不用加一

class Solution {
public:
    vector<vector<int>>result;
    vector<int>path;
    void backtracking(vector<int>& candidates, int target, int sum, int startIndex) {
        //终止条件
        if (sum == target) {
            result.push_back(path);
            return ;
        }

        if (sum > target) {
            return ;
        }

        //单层循环逻辑
        for (int i = startIndex; i < candidates.size(); i++) {
            path.push_back(candidates[i]);
            sum += candidates[i];
            backtracking(candidates, target, sum, i);
            sum -= candidates[i];
            path.pop_back();
        }

    }
    vector<vector<int>> combinationSum(vector<int>& candidates, int target) {
        backtracking(candidates, target, 0, 0);
        return result;
    }
};
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30

二、组合总和II

和组合总和思路差不多,但不允许同一元素多次选取,同时不能有重复的组合,需要去重
一种是usd去重,一种是startIndex去重,树层去重和树枝去重

class Solution {
public:
    vector<vector<int>>result;
    vector<int>path;
    void backtracking (vector<int>& candidates, int target, int sum, int startIndex, vector<bool>&usd) {
        //终止条件
        if (sum > target) return ;
        if (sum == target) {
            result.push_back(path);
            return ;
        }

        //单层循环逻辑 //去重
        for (int i = startIndex; i < candidates.size(); i++) {
            //去重
            if (i > 0 && candidates[i] == candidates[i-1] && usd[i-1] == false) continue;
            path.push_back(candidates[i]);
            sum += candidates[i];
            usd[i] = true;
            backtracking(candidates, target, sum, i+1, usd);
            sum -= candidates[i];
            usd[i] = false;
            path.pop_back();
        }
    }
    vector<vector<int>> combinationSum2(vector<int>& candidates, int target) {
        vector<bool> usd(candidates.size(), false);
        //排序
        sort(candidates.begin(), candidates.end());
        backtracking(candidates, target, 0, 0, usd);
        return result;
    }
};
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33

三、分割回文串

思路和组合大致相同,只不过是利用startIndex作为字符串的开头,i作为字符串的末尾,判断是否是回文串

class Solution {
public:
    vector<vector<string>>result;
    vector<string>path;
    
    //回文串判断
    bool isHuiWen (string s, int begin, int end) {
        for (int i = begin, j = end; i < j; i++, j--) {
            if (s[i] != s[j]) {
                return false;
            }
        }
        return true;
    }

    void backtracking(string s, int stratIndex) {
        //终止条件
        if (stratIndex >= s.size()) {
            result.push_back(path);
            return ;
        }

        //单层搜索逻辑
        for (int i = stratIndex; i < s.size(); i++) {
            if (isHuiWen(s, stratIndex, i)) {
                string str = s.substr(stratIndex, i - stratIndex + 1);
                path.push_back(str);
            }
            else continue;
            backtracking(s, i+1);
            path.pop_back();
        }

    }
    vector<vector<string>> partition(string s) {
        backtracking(s, 0);
        return result;
    }
};
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39

总结

回文串切割有点不太好理解,但还是固定模板,多多练习
学习时间110min。2023.4.1
学习资料:《代码随想录》

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/知新_RL/article/detail/582093
推荐阅读
相关标签
  

闽ICP备14008679号