力扣:131.分割回文串
1、题目描述
给你一个字符串 s,请你将 s 分割成一些子串,使每个子串都是 回文串 。返回 s 所有可能的分割方案。
回文串 是正着读和反着读都一样的字符串。
示例 1:
输入:s = “aab”
输出:[[“a”,“a”,“b”],[“aa”,“b”]]
示例 2:输入:s = “a”
输出:[[“a”]]来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/palindrome-partitioning
2、思路
首先,需要一个函数判断是否是回文串,判断回文串根据回文串的定义从两头向中间遍历,看是否对称(两个指针指向的值相等),若不相等则返回false,否则true。
该部分代码如下:
bool isp(string&s,int begin,int end){
for(int i =begin,j=end;i<j;i++,j--){
if(s[i]!=s[j])return false;
}
return true;
}
其次是解决该问题的重点部分,我在这里使用回溯算法进行求解。
回溯的思路为,对任何长度的字符串都进行分割进行判断,for循环控制分割字符串的长度,回溯递归控制分割字符串的数量(长度小,则数量多,反之亦然)。
回溯的返回条件为,分割的index大于等于字符串的长度。
if(index>=s.size()){
res.push_back(path);
return;
}
剪枝为当此次要切割的字符串不为回文串则跳过此次切割。只有在分割出来的字符串为回文串才会继续向下回溯递归。
for(...){
if(isp(s,index,i)){
path.push_back(s.substr(index,i-index+1));
}else{
continue;
}
...
}
3、完整代码:
class Solution {
public:
vector<vector<string>> res;
vector<string>path;
//回文串判断函数
bool isp(string&s,int begin,int end){
for(int i =begin,j=end;i<j;i++,j--){
if(s[i]!=s[j])return false;
}
return true;
}
void bt(string&s,int index){
//回溯中止条件,分割的起点到尾部
if(index>=s.size()){
res.push_back(path);
return;
}
for(int i =index;i<s.size();i++){
if(isp(s,index,i)){
path.push_back(s.substr(index,i-index+1));
}else{
continue;
}
bt(s,i+1);
path.pop_back();
}
}
vector<vector<string>> partition(string s) {
bt(s,0);
return res;
}
};
执行用时:96 ms, 在所有 C++ 提交中击败了89.99%的用户
内存消耗:74 MB, 在所有 C++ 提交中击败了60.20%的用户
通过测试用例:32 / 32