方法一,DFS遍历,每次保证start参数之前的字串部分已经处理,[start, s.size()-1]部分待处理,针对该部分中的每一个位置i,如果[start,i]是一个palindrome串,则将子串[start,i]添加到path中,并进一步递归。时间O(2^n),空间O(n)。
class Solution {
public:
vector<vector<string>> partition(string s) {
vector<vector<string> > result;
vector<string> path;
dfs(s, result, path, 0);
return result;
}
void dfs(string &s, vector<vector<string> > &result, vector<string> &path, int start)
{
if(start == s.size())
{
result.push_back(path);
return;
}
for(int i=start; i<s.size(); ++i)
{
if(isPalindrome(s, start, i))
{
path.push_back(s.substr(start, i-start+1));
dfs(s, result, path, i+1);
path.pop_back();
}
}
}
bool isPalindrome(string s, int start, int end)
{
while(start <= end && s[start] == s[end])
{
start++;
end--;
}
return start > end;
}
};
方法二: DP。 first compute whether each substring is palindrome using dp. then compute the partitioning result of each substring s[0,...i]
class Solution {
public:
vector<vector<string>> partition(string s) {
const int n = s.size();
if(n == 0)
return vector<vector<string> >();
vector<vector<bool> > f(n, vector<bool>(n, false));
for(int i=0; i<n; i++)
f[i][i] = true;
for(int L = 2; L<=n; L++)
{
for(int start=0; start <= n-L; start++)
{
int end = start+L-1;
if(L == 2)
f[start][end] = (s[start] == s[end]);
else
f[start][end] = (s[start] == s[end]) && f[start+1][end-1];
}
}
vector<vector<string> > result[n+1];
result[0] = {{}};
for(int i=0; i<n; i++)
{
for(int j=-1; j<i; j++)
{
if(f[j+1][i])
{
for(auto vec: result[j+1])
{
vec.push_back(s.substr(j+1, i-j));
result[i+1].push_back(vec);
}
}
}
}
return result[n];
}
};