Given a string s, partition s such that every substring of the partition is a palindrome.
Return all possible palindrome partitioning of s.
For example, given s = "aab"
,
Return
[ ["aa","b"], ["a","a","b"] ]
这样的题目,首先使用O(n^2)的求回文最长回文子串的方法,如果暴力求解,就是n^3。
动态规划,可以变成O(o^2).算法如下。
s表示字符串。
dp[i][j] 为true,表示字符串从i到j是一个回文串;接着进行推理,如果s[i-1]==s[j+1]并且dp[i][j]为true,那么字符串的字串从(i-1到j+1)就是一个回文串了。所以算法是双重循环,dp[i][j] = true 的条件有 1:i==j; 2: s[i]==s[j]并且dp[i-1][j-1]为true。
通过dp求得回文串之后,可以通过深度优先搜索,因为每次dp[i][j]为true的地方对字符串进行分割,就一定是回文字串。
//8:09
class Solution {
public:
vector<vector<string> > res;
vector<vector<string>> partition(string s) {
int len = s.size();
vector<vector<bool> > dp(len,vector<bool>(len,false));
int i,j;
//先求dp[i][i] 和dp[i][i+1],后面在进行迭代
for(i=0;i<len;i++){
dp[i][i] = true;
if(i+1<len && s[i]==s[i+1])
{
dp[i][i+1] = true;
}
}
//求字符串的任意两个位置之间是否符合回文
for(i=1;i<len-1;i++)
{
for(j=0;j<len-i-1;j++)
{
if(dp[j+1][j+i]&&s[j]==s[j+i+1])
{
dp[j][j+i+1] = true;
}
}
}
vector<string> sol;
dfs(dp,sol,0,len,s);
return res;
}
//搜索出所有的字符串分割方式
void dfs(vector<vector<bool> > &dp,vector<string> &solve,int s,int len,string &ori)
{
if(s==len)
{
res.push_back(solve);
return ;
}
for(int i=s;i<len;i++)
{
//从s开始,所有后面的字串都是一个新的分割方式
if(dp[s][i])
{
solve.push_back(ori.substr(s,i-s+1));
dfs(dp,solve,i+1,len,ori);
solve.pop_back();
}
}
return ;
}
};
没看懂的博友可以通过评论和我讨论。