leetcode 131. 分割回文串

问题描述

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

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

示例:

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

代码

class Solution {
public:
    vector<string> path;
    vector<vector<string>> ans;
    vector<vector<string>> partition(string s) {
         backtrack(s,0);
         return ans;
    }
    bool check(string& s,int begin,int end)
    {
        while(begin<end)
        {
            if(s[begin]==s[end])
            {
                ++begin;
                --end;
            }
            else{
                return false;
            }
        }
        return true;
    }
    void backtrack(string& s,int begin)
    {
        if(begin == s.size())
        {
            ans.push_back(path);
            return;
        }
        for(int i = begin; i < s.size(); ++i)
        {
            if(check(s,begin,i))//检查s[begin,i]是否是回字子串
            {
                path.push_back(s.substr(begin,i-begin+1));
                backtrack(s,i+1);//再检查s[i+1:s.size()-1]部分
                path.pop_back();
            }
        }
    }
};

结果

执行用时 :12 ms, 在所有 C++ 提交中击败了93.37%的用户
内存消耗 :10.2 MB, 在所有 C++ 提交中击败了100.00%的用户

代码2

使用额外的空间事先记录回文子串,减少在回溯中判断所需要的计算量。

class Solution {
public:
    vector<string> path;
    vector<vector<string>> ans;
    
    vector<vector<string>> partition(string s) {
        int n = s.size();
        vector<vector<bool>> dp(n,vector<bool>(n,false));//dp[i][j]代表s[i,j]是否是回文子串
        for(int j = 0; j < n; ++j)
        {
            for(int i = 0; i <= j; ++i)
            {
                if(s[i]==s[j] &&(j-i <=2 || dp[i+1][j-1]))
                    dp[i][j] = true;
            }
        }
        backtrack(s,0,dp);
        return ans;
    }
    void backtrack(string& s,int begin,vector<vector<bool>> &dp)
    {
        if(begin == s.size())
        {
            ans.push_back(path);
            return;
        }
        for(int i = begin; i < s.size(); ++i)
        {
            if(dp[begin][i])//检查s[begin,i]是否是回字子串
            {
                path.push_back(s.substr(begin,i-begin+1));
                backtrack(s,i+1,dp);//再检查s[i+1:s.size()-1]部分
                path.pop_back();
            }
        }
    }
};

结果

执行用时 :12 ms, 在所有 C++ 提交中击败了93.37%的用户
内存消耗 :10.2 MB, 在所有 C++ 提交中击败了100.00%的用户

好吧,没啥区别。。。

posted @ 2020-06-07 14:11  曲径通霄  阅读(112)  评论(0编辑  收藏  举报