0%

palindrome-partitioning

题目描述

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

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

题解

分两步。第一步对s使用dp方法确定回文子串。第二步使用回溯法进行分割。

第一步,dp[i][j]代表s(i,j)是否为回文(包含i和j)字符串,注意当ij之间的字符大于等于3个时,dp[i][j]=dp[i+1][j-1]&&s[i]\==s[j],即i递减,j递增,又j>=i,即可确定i,j的递推方向。第二步,dfs(ps),将对dp[ps][i] (ps<=i<n)中为true的,s(ps,i)放入组合,进行dfs,当ps==n时,当前组合放入结果。注意dfs的优化,模版类使用传址,复用变量(如字符串s的大小)使用全局变量。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
int len; bool **dp;
void dfsHelper(string& s,int ps, vector<string>& tmp, vector<vector<string>>& res)
{
if (ps >=len)
{
res.push_back(tmp);
return;
}
for (int i = ps; i < len; i++)
{
if (dp[ps][i])
{
tmp.push_back(s.substr(ps, i - ps + 1));
dfsHelper(s, i+1, tmp, res);
tmp.pop_back();
}
}
}
vector<vector<string>> partition(string s) {
len = s.length();
dp =new bool*[len];
for (int i = 0; i < len; i++)
dp[i] = new bool[len];
for (int i = 0; i < len; i++)
for (int j = 0; j < len; j++)
dp[i][j] = 0;
for (int i = 0; i < len; i++)
dp[i][i] = 1;
for (int i = 1; i < len; i++)
dp[i][i - 1] = 1;
for (int i = 1; i < len; i++)
{
for (int j = 0; j < len - i; j++)
{
dp[j][j + i] = dp[j + 1][j + i - 1] && (s[j] == s[j + i]);
}
}
vector<string> tmp = {};
vector<vector<string>> res;
dfsHelper(s, 0, tmp, res);
return res;
}