day23 第七章 回溯算法part02

发布于:2025-03-01 ⋅ 阅读:(107) ⋅ 点赞:(0)
组合问题:
同一个集合,startindex
        允许重复元素startindex从i开始
        不允许重复元素,startindex从i+1开始
不同集合,index(可以用for,不用用回溯)
for循环,横向遍历,控制组合不重复;
递归,for内部,纵向便利,控制组合内元素如何构成。

回溯算法理论基础

剪枝从元素个数和元素和入手,元素和用排序+剪枝,都是在for的结束上做文章

39. 组合总和

如果是一个集合来求组合的话,就需要startIndex,例如:77.组合 (opens new window)216.组合总和III (opens new window)

如果是多个集合取组合,各个集合之间相互不影响,那么就不用startIndex,例如:17.电话号码的字母组合

在求和问题中,排序之后加剪枝是常见的套路!

class Solution {
public:
    void backtracing(vector<vector<int>>& res, vector<int>& path, vector<int>& candidates, int target, int sum, int start_index){
        if(target<sum){
            return;
        }
        if(target==sum){
            res.push_back(path);
            return;
        }

        for(int i=start_index;i<candidates.size() && sum+candidates[i]<=target;i++){
            path.push_back(candidates[i]);
            sum += candidates[i];
            backtracing(res, path, candidates, target, sum, i);
            sum -= candidates[i];
            path.pop_back();
        }
    }
    vector<vector<int>> combinationSum(vector<int>& candidates, int target) {
        vector<vector<int>> result;
        vector<int> path;
        sort(candidates.begin(), candidates.end());
        backtracing(result, path, candidates, target, 0, 0);
        return result;
    }
};

40.组合总和II

组合不能重复:

同层/树层

for()怎么循环

元素不能重复:

backtracing(...,i+1,...)

for循环控制的是组合,for里面控制的是深度,元素怎么构建。

class Solution {
public:
    void backtracing(vector<vector<int>>& res, vector<int>& path, vector<int>& candidates, int target, int sum, int start_index){
        if(sum>target){
            return;
        }
        if(sum==target){
            res.push_back(path);
            return;
        }

        for(int i=start_index;i<candidates.size()&&sum+candidates[i]<=target;i++){
            if(i>start_index && candidates[i]==candidates[i-1]){
                continue;
            }
            sum += candidates[i];
            path.push_back(candidates[i]);
            backtracing(res, path, candidates, target, sum, i+1);
            sum -= candidates[i];
            path.pop_back();
        }

    }
    vector<vector<int>> combinationSum2(vector<int>& candidates, int target) {
        vector<vector<int>> result;
        vector<int> path;
        sort(candidates.begin(),candidates.end());
        backtracing(result, path, candidates, target, 0, 0);
        return result;
    }
};

131.分割回文串

分割问题跟组合问题一样,都是重叠子问题+记录path。注意定义好分割的区间。

class Solution {
public:
    void backtracking(vector<vector<string>>& res, vector<string>& path, string s, int start_index){
        if(start_index>=s.size()){
            res.push_back(path);
            return;
        }

        for(int i=start_index;i<s.size();i++){
            string mid = s.substr(start_index, i-start_index+1);
            if(isHuiwenchuan(mid)){
                path.push_back(mid);
                backtracking(res, path, s, i+1);
                path.pop_back();
            }
        }
    }
    bool isHuiwenchuan(string s){
        for(int i=0,j=s.size()-1;i<j;i++,j--){
            if(s[i] != s[j]){
                return false;
            }
        }
        return true;
    }
    vector<vector<string>> partition(string s) {
        vector<vector<string>> result;
        vector<string> path;
        backtracking(result, path, s, 0);
        return result;
        
    }
};


网站公告

今日签到

点亮在社区的每一天
去签到