思路:
首先使用回溯法来排列并判断所有情况,同时是用动态规划来实现判断子字符串是否是回文串。
该题中回溯法的循环像是分治法,首先判断前一部分的子字符串是不是回文串,如果是的话,就对其余的后一部分再进行重复的判断。
原题链接:https://leetcode.cn/problems/palindrome-partitioning/description/?favorite=2ckc81c
1.题目如下:
给你一个字符串 s,请你将 s 分割成一些子串,使每个子串都是 回文串 。返回 s 所有可能的分割方案。
回文串 是正着读和反着读都一样的字符串。
示例 1:
输入:s = "aab"
输出:[["a","a","b"],["aa","b"]]
示例 2:
输入:s = "a"
输出:[["a"]]
提示:
1 <= s.length <= 16
s 仅由小写英文字母组成
2.代码如下:
class Solution {
private:
vector<vector<int>> f;
vector<vector<string>> ans;
int n;
public:
//思路一:用回溯法 + 动态规划
vector<vector<string>> partition(string s) {
vector<string> temp;
n = s.size();
f.assign(n, vector<int>(n, true));
//动态规划是用来记录子字符串是否为回文串,提高判断效率
for(int i=s.length()-1;i>=0;--i) {
for (int j=i+1;j<s.length();++j) {
f[i][j]=(s[i]==s[j])&&f[i+1][j-1];
}
}
backTrack(s,temp,0);
return ans;
}
//回溯
void backTrack(string s,vector<string> temp,int dp){
if(dp==s.length()){
ans.push_back(temp);
return ;
}
// 从dp=0开始回溯
// 首先单个字符肯定是回文串,那么进行下一层;
// 然后同层再增长字符串,如果子字符串是回文串,同样进入下层直到深度到size
for (int i=dp;i<s.length();++i) {
if (f[dp][i]) {
temp.push_back(s.substr(dp,i-dp+1));
backTrack(s,temp,i+1);
temp.pop_back();
}
}
}
};