Bootstrap

LeetCode 131. 分割回文串(C++)

思路:
首先使用回溯法来排列并判断所有情况,同时是用动态规划来实现判断子字符串是否是回文串。
该题中回溯法的循环像是分治法,首先判断前一部分的子字符串是不是回文串,如果是的话,就对其余的后一部分再进行重复的判断。
原题链接:https://leetcode.cn/problems/palindrome-partitioning/description/?favorite=2ckc81c

1.题目如下:

给你一个字符串 s,请你将 s 分割成一些子串,使每个子串都是 回文串 。返回 s 所有可能的分割方案。

回文串 是正着读和反着读都一样的字符串。

示例 1:

输入:s = "aab"
输出:[["a","a","b"],["aa","b"]]

示例 2:

输入:s = "a"
输出:[["a"]]
 

提示:

1 <= s.length <= 16
s 仅由小写英文字母组成

2.代码如下:

class Solution {
private:
    vector<vector<int>> f;
    vector<vector<string>> ans;
    int n;
public:
//思路一:用回溯法 + 动态规划
    vector<vector<string>> partition(string s) {
        vector<string> temp;
        n = s.size();
        f.assign(n, vector<int>(n, true));
        //动态规划是用来记录子字符串是否为回文串,提高判断效率
        for(int i=s.length()-1;i>=0;--i) {
            for (int j=i+1;j<s.length();++j) {
                f[i][j]=(s[i]==s[j])&&f[i+1][j-1];
            }
        }
        backTrack(s,temp,0);
        return ans;
    }
    //回溯
    void backTrack(string s,vector<string> temp,int dp){
        if(dp==s.length()){
            ans.push_back(temp);
            return ;
        }
        // 从dp=0开始回溯
        // 首先单个字符肯定是回文串,那么进行下一层;
        // 然后同层再增长字符串,如果子字符串是回文串,同样进入下层直到深度到size
        for (int i=dp;i<s.length();++i) {
            if (f[dp][i]) {
                temp.push_back(s.substr(dp,i-dp+1));
                backTrack(s,temp,i+1);
                temp.pop_back();
            }
        }

    }
};
;