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%的用户
好吧,没啥区别。。。