Day23| 39.组合总和、40.组合总和II、131.分割回文串

2025-07-31

39.组合总和

题目链接:39.组合总和
文档讲解:代码随想录
状态:轻松AC

思路

本题的前置条件很多,如无重复元素等等,这个题目很好做,与之前的组合问题不同的是可以无限制重复选取元素

注意: 既然可以重复选取,每次递归不必后移,树层之间(for循环)自然终止条件没有了,要额外添加终止条件。

题解

class Solution {
public:
    vector<vector<int>> res;
    vector<int> path;
    int sum;
    void backtracking(vector<int>& candidates, int target,int start)
    {
        if(target<0)return;
        if(target == 0)
        {
            res.push_back(path);
            return ;
        }
        for(int i = start;i<candidates.size();i++)
        {
            path.push_back(candidates[i]);
            backtracking(candidates, target-candidates[i],i);
            path.pop_back();
        }
    }
    vector<vector<int>> combinationSum(vector<int>& candidates, int target) {

        backtracking(candidates,target,0);
        return res;
    }
};

40.组合总和II

题目链接:40.组合总和II
文档讲解:代码随想录
状态:利用去重思想,AC,很爽

思路

去重思路:之前做过三数之和,知道要sort先给排个序,为何?组合重复是因为里面由相同元素,要跳过相同元素就要把他们放在一起,所以排序理所应当也必不可少。

去重图解:

chart

去重中注意使用while,以及注意在条件中保证不要越界

题解

class Solution {
public:
    vector<vector<int>> res;
    vector<int> path;
    void backtracking(vector<int>& candidates, int target,int start)
    {
        if(target<0)return;
        if(target == 0)
        {
            res.push_back(path);
            return ;
        }
        for(int i = start;i<candidates.size();i++)
        {
            path.push_back(candidates[i]);

            backtracking(candidates, target-candidates[i],i+1);
            while(i<candidates.size()-1 && candidates[i] == candidates[i+1])i++;
            path.pop_back();
        }
    }
    vector<vector<int>> combinationSum2(vector<int>& candidates, int target) {
        sort(candidates.begin(),candidates.end());
        for(auto i:candidates)cout<<i;
        backtracking(candidates, target, 0);
        return res;
    }
};

131.分割回文串

题目链接:131.分割回文串
文档讲解:代码随想录
状态:对于分割问题糊涂了,不会

思路

读题读题再读题,题目要求是满足分割得到的字串都是回文串

分割问题与组合问题类似,只不过把数组中的元素转变为了字符串中的边界。

从头手动画图理清思路极其重要,要不然很容易糊涂。

题解

class Solution {
public:
    vector<string> part;
    vector<vector<string>> res;
    bool isagain(string s)
    {
        string s1 = s;
        reverse(s.begin(), s.end());
        if(s1 == s)return true;
        else return false;
    }
    void backtrackint(string s)
    {
        if(s.empty())
        {
            res.push_back(part);
            return;
        }
        for(int i = 1;i<=s.size();i++)
        {
            string temp(s.begin(),s.begin()+i);
            
            if(isagain(temp))
            {//必须得是回文串才能进一步操作
             //必须得是回文串才有资格push,当然也才有资格pop
                part.push_back(temp);
                string temp1(s.begin()+i,s.end());
                backtrackint(temp1);
                part.pop_back();
            } 
        }
    }
    vector<vector<string>> partition(string s) {
        backtrackint(s);
        return res; 
    }
};