131.分割字符串

给定一个字符串 s,将 s 分割成一些子串,使每个子串都是回文串。

返回 s 所有可能的分割方案。

示例:

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

回溯法

    bool isPalindrome(string s,int start,int i){
        while(start<=i){
            if(s[start]!=s[i]) return false;
            start++;
            i--;
        }
        return true;
    }
    void dfs(string s,int start,vector<string> out,vector<vector<string>>&res){
        if(start==s.size()) res.push_back(out);
        else{
            for(int i=start;i<s.size();++i){
                if(!isPalindrome(s,start,i)) continue;
                out.push_back(s.substr(start,i-start+1));
                dfs(s,i+1,out,res);
                out.pop_back();
            }
        }
    }
    vector<vector<string>> partition(string s) {
        vector<vector<string>> res;
        vector<string> out;
        dfs(s,0,out,res);
        return res;
    }

改进

之前的方法每一个子串都要独自判断,可以先建立好字符串s的子串回文的dp数组。当我们建立好这样一个二维数组dp,其中 dp[i][j] 表示 [i, j] 范围内的子串是否为回文串,这样就不需要另外的子函数去判断子串是否为回文串了,大大的提高了计算的效率。

    void dfs(string s,int start,vector<string> out,vector<vector<string>>&res,vector<vector<int>> dp){
        if(start==s.size()) res.push_back(out);
        else{
            for(int i=start;i<s.size();++i){
                if(!dp[start][i]) continue;
                out.push_back(s.substr(start,i-start+1));
                dfs(s,i+1,out,res,dp);
                out.pop_back();
            }
        }
    }
    vector<vector<string>> partition(string s) {
        int n=s.size();
        vector<vector<string>> res;
        vector<string> out;
        vector<vector<int>> dp(n,vector<int>(n,0));
        //需要j在外层循环
        for(int j=0;j<n;++j)
            for(int i=0;i<=j;++i){
                if(j-i<2) dp[i][j]=(s[i]==s[j]);
                else if(s[i]==s[j]&&dp[i+1][j-1]) dp[i][j]=1;
            }
        dfs(s,0,out,res,dp);
        return res;
    }
原文地址:https://www.cnblogs.com/Frank-Hong/p/13354283.html