1、深度优先搜索+回溯
我们可以利用深度优先搜索,每次假设字符串中[0,i]的位置已经都是回文串,我们只需要继续判断当前连续的回文串的下一个位置[i,j]即可。同时为了加快回文串的判断,我们使用数组dp保存当前区间的字符串是否为回文串。
class Solution {
private:
vector<vector<int>> dp;
vector<vector<string>> ret;
vector<string> ans;
int n;
public:
void dfs(const string& s, int i) {
if (i == n) {
ret.push_back(ans);
return;
}
for (int j = i; j < n; ++j) {
if (dp[i][j]) {
ans.push_back(s.substr(i, j - i + 1));
dfs(s, j + 1);
ans.pop_back();
}
}
}
vector<vector<string>> partition(string s) {
n = s.size();
dp.assign(n, vector<int>(n, true));
for (int i = n - 1; i >= 0; --i) {
for (int j = i + 1; j < n; ++j) {
dp[i][j] = (s[i] == s[j]) && dp[i + 1][j - 1];
}
}
dfs(s, 0);
return ret;
}
};
2、记忆化搜索+回溯
利用记忆化搜索代替动态规划预处理。
class Solution {
private:
vector<vector<int>> f;
vector<vector<string>> ret;
vector<string> ans;
int n;
public:
void dfs(const string& s, int i) {
if (i == n) {
ret.push_back(ans);
return;
}
for (int j = i; j < n; ++j) {
if (isPalindrome(s, i, j) == 1) {
ans.push_back(s.substr(i, j - i + 1));
dfs(s, j + 1);
ans.pop_back();
}
}
}
// 记忆化搜索中,f[i][j] = 0 表示未搜索,1 表示是回文串,-1 表示不是回文串
int isPalindrome(const string& s, int i, int j) {
if (f[i][j]) {
return f[i][j];
}
if (i >= j) {
return f[i][j] = 1;
}
return f[i][j] = (s[i] == s[j] ? isPalindrome(s, i + 1, j - 1) : -1);
}
vector<vector<string>> partition(string s) {
n = s.size();
f.assign(n, vector<int>(n));
dfs(s, 0);
return ret;
}
};