方法一:回溯法
蓝色框为选择列表,判断截取部分是否为回文串进行枝剪。
class Solution {
public:
vector<vector<string>> res; //保存结果
void backtrack(vector<string>& track,string s,int start){
if(start==s.size()){ //满足条件返回
res.push_back(track);
return ;
}
for(int i=start;i<s.size();i++){
if(!checkstr(s,start,i)) //枝剪,如果截取部分不是回文串返回
continue;
track.push_back(s.substr(start,i-start+1)); //做出选择
backtrack(track,s,i+1);
track.pop_back(); //撤销选择
}
}
bool checkstr(string s,int left,int right){ //判断是否回文字符串
while(left<right){
if(s[left]!=s[right])
return false;
left++;
right--;
}
return true;
}
vector<vector<string>> partition(string s) {
if(s.empty()) return res;
vector<string> track; //路径
backtrack(track,s,0); //参数:路径,选择列表,选择列表开始位置
return res;
}
};
优化:dp优化回文串判断
class Solution {
public:
vector<vector<string>> res; //保存结果
void backtrack(vector<string>& track,string s,int start,vector<vector<bool>> dp){
if(start==s.size()){ //满足条件返回
res.push_back(track);
return ;
}
for(int i=start;i<s.size();i++){
if(!dp[start][i]) //枝剪,如果截取部分不是回文串返回
continue;
track.push_back(s.substr(start,i-start+1)); //做出选择
backtrack(track,s,i+1,dp);
track.pop_back(); //撤销选择
}
}
vector<vector<string>> partition(string s) {
if(s.empty()) return res;
//dp:状态dp[i][j]表示s[i][j]是否为回文
vector<vector<bool>> dp(s.size(),vector<bool>(s.size(),false));
//状态转移方程
for(int right=0;right<s.size();right++){
for(int left=0;left<=right;left++){
if(s[left]==s[right] && (right-left<=2 || dp[left + 1][right - 1]))
dp[left][right]=true;
}
}
vector<string> track; //路径
backtrack(track,s,0,dp); //参数:路径,选择列表,选择列表开始位置
return res;
}
};