- 分割回文串
给你一个字符串 s,请你将 s 分割成一些子串,使每个子串都是 回文串 。返回 s 所有可能的分割方案。
回文串 是正着读和反着读都一样的字符串。
示例 1:
输入:s = “aab”
输出:[[“a”,“a”,“b”],[“aa”,“b”]]
示例 2:
输入:s = “a”
输出:[[“a”]]
提示:
1 <= s.length <= 16
s 仅由小写英文字母组成
题解
动态规划直接分割,然后用动态数组res储存下每个区间能得到的答案res[i][j],那么如果区间[0,j]是回文串,区间[j+1,i]是回文串,那么[0,i]就是这两个区间的动态数组两两匹配得到。
AC代码
class Solution {
public:
bool vis[20][20];
void fun(string s,int pos)
{
for(int i=pos,j=pos;i>=0&&j<s.length();i--,j++)
{
if(s[i]==s[j])
vis[i][j]=true;
else break;
}
for(int i=pos,j=pos+1;i>=0&&j<s.length();i--,j++)
{
if(s[i]==s[j])
vis[i][j]=true;
else break;
}
}
void init(string s)
{
memset(vis,0,sizeof(vis));
for(int i=0;i<s.length();i++)
fun(s,i);
}
bool dp[20][20];
vector<vector<string>>res[20][20];
vector<vector<string>> partition(string s)
{
init(s);
memset(dp,0,sizeof(dp));
for(int i=0;i<s.length();i++)
{
for(int j=i;j<s.length();j++)
{
if(vis[i][j])
{
dp[i][j]=true;
string t="";
for(int k=i;k<=j;k++)
t+=s[k];
vector<string>p;
p.push_back(t);
res[i][j].push_back(p);
}
}
}
for(int i=0;i<s.length();i++)
{
for(int j=0;j<i;j++)
{
if(dp[0][j]&&vis[j+1][i])
{
dp[0][i]=true;
for(int k=0;k<res[0][j].size();k++)
{
for(int l=0;l<res[j+1][i].size();l++)
{
// cout<<i<<" "<<j<<" "<<k<<" "<<l<<endl;
vector<string>p;
for(int h=0;h<res[0][j][k].size();h++)
p.push_back(res[0][j][k][h]);
for(int h=0;h<res[j+1][i][l].size();h++)
p.push_back(res[j+1][i][l][h]);
res[0][i].push_back(p);
}
}
}
}
}
return res[0][s.length()-1];
}
};