https://leetcode.com/problems/palindrome-partitioning/
一般这种求全部排列的都是用DFS+backtracing解决。但是求s[i…j]是否是回文,如果将字符串倒序,然后判断,难免太浪费时间。可以先用动态规划求解然后再进行回溯。回溯的思想就是从一个位置出发,依次对其后的位置进行substr截取,判断是否为回文串,然后再从该位置出发继续进行判断。回溯剪枝的条件是不是回文字符串。
动态规划的思想是:
palind[i][j]=palind[i+1][j-1]&&s[i]==s[j]
这里需要注意的是对于下标i是i+1,表示i位置依赖于i+1的判断,所以下标i的方向是从大向小,而j的判断依赖于j-1所以j的下标位置是从小向大的。
动归部分代码:
for(int i=n-1;i>=0;i--){
for(int j=i;j<n;j++){
if((i+1>=j-1||palind[i+1][j-1])&&s[i]==s[j]) palind[i][j]=true;
}
}
整体部分代码:
class Solution {
private:
vector<vector<string> > res;
vector<string> subres;
public:
vector<vector<string>> partition(string s) {
int n=s.size();
vector<vector<bool> > palind(n,vector<bool>(n,false));
for(int i=n-1;i>=0;i--){
for(int j=i;j<n;j++){
if((i+1>=j-1||palind[i+1][j-1])&&s[i]==s[j]) palind[i][j]=true;
}
}
getPartition(s,0,palind);
return res;
}
void getPartition(string &s,int start,vector<vector<bool> > palind){
if(start==s.size()){
res.push_back(subres);
return;
}
for(int i=start;i<s.size();i++){
if(palind[start][i]){
subres.push_back(s.substr(start,i-start+1));
getPartition(s,i+1,palind);
subres.pop_back();
}
}
}
};