分割回文串
给定一个字符串 s,将 s 分割成一些子串,使每个子串都是回文串。
返回 s 所有可能的分割方案。
示例:
输入: “aab”
输出:
[
\quad
[“aa”,“b”],
\quad
[“a”,“a”,“b”]
]
思路:
直观想法,采用递归方式,设计函数
f
f
f,先分割出一个回文串子串,再把剩余的字符串子串继续使用函数
f
f
f,再求一个回文串子串,一直重复到剩余子串为空。
回溯法:按深度优先策略搜索问题的解空间树。首先从根节点出发搜索解空间树,当算法搜索至解空间树的某一节点时,先利用剪枝函数判断该节点是否可行(即能得到问题的解)。如果不可行,则跳过对该节点为根的子树的搜索,逐层向其祖先节点回溯;否则,进入该子树,继续按深度优先策略搜索。(参考链接1)
代码:
class Solution {
public:
//判断是否是回文字符串,参考链接3
bool isPalindrome(string s) {
string tmp_s;
for(auto p:s)
{
if(('a'<=p && p<='z' )|| ('A'<=p && p<= 'Z') || ('0'<=p && p<='9'))
tmp_s+=p;
}
transform(tmp_s.begin(),tmp_s.end(),tmp_s.begin(),::tolower);
int i=0,j=tmp_s.length()-1;
while(i<=j)
{
if(tmp_s[i++]!=tmp_s[j--])
return false;
}
return true;
}
//递归函数
void getSubPalindrome(string s, vector<string> & tmp_vec_str, vector<vector<string>> & final_vec_str)
{
string tmp_s1,tmp_s2;
if(s.length()==0)
{
final_vec_str.push_back(tmp_vec_str);
}
for(int i=1;i<=s.length();i++) //遍历的是长度,非索引
{
tmp_s1=s.substr(0,i);
tmp_s2=s.substr(i,s.length()-i);
if(isPalindrome(tmp_s1))
{
tmp_vec_str.push_back(tmp_s1);
getSubPalindrome(tmp_s2,tmp_vec_str,final_vec_str); //递归求解
tmp_vec_str.pop_back(); //递归到最后一次,则第一次执行此处,再一步步的清空tmp_vec_str
}
}
}
//主函数
vector<vector<string>> partition(string s) {
vector<vector<string>> final_vec_s;
vector<string> tmp_vec_s;
getSubPalindrome(s,tmp_vec_s,final_vec_s);
return final_vec_s;
}
};
结果:
参考链接:
[1] GoRustNeverStop: [回溯算法] 五大常用算法之回溯法
[2] 码源: 力扣131.分割回文串
[3] 消失男孩:[LeetCode][C++]验证回文串