题目:131. 分割回文串
难度: 中等
题目:
给你一个字符串 s,请你将 s 分割成一些子串,使每个子串都是 回文串 。返回 s 所有可能的分割方案。
回文串 是正着读和反着读都一样的字符串。
示例1
输入:s = "aab"
输出:[["a","a","b"],["aa","b"]]
示例2
输入:s = "a"
输出:[["a"]]
提示
- 1 <= s.length <= 16
- s 仅由小写英文字母组成
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/palindrome-partitioning/
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
解题思路
首先,回文串是从前往后读和从后往前读都一致的字符串,比如:aba、a、aa、abcba等等。判断是否有回文串有很多方法,而我使用的方法就是:循环遍历字符串s的元素,如果遍历中的任意i,s[i] == s[len-i-1],那么该字符串为回文串。
而由题意,需要求出s中子串为回文串的所有可能情况,也就是说,子串都为回文串,且需要返回所有的可能情况。
因此,可以想象,需要分割s并判断是否为回文串,如果是则将剩余子串继续相同的操作,那么很容易想到利用递归算法层层剖析。也就是回溯算法,类似于树的结构,逐层分支判断是否为回文串。
解题代码
class Solution {
private:
vector<vector<string>> sums;
vector<string> nums;
public:
//用于判断是否为回文串
bool isPalString(string s)
{
int len = s.size();
for (int i = 0; i < len/2; i++)
{
if (s[i] != s[len - 1 - i])
{
return false;
}
}
return true;
}
//递归遍历
void DFs(string s, bool isLast)
{
bool flag;
int len = s.size();
//如果已经是最后一个字符串了,加入sums中
if(isLast)
{
sums.push_back(nums);
return;
}
for (int i = 0; i < len; i++)
{
flag = false;
string s1 = s.substr(0, len - i);
if (isPalString(s1))//如果为回文串
{
nums.push_back(s1);
//i=0表明无需继续查找后面字符了,已经到头了
if(i == 0)
flag = true;
s1 = s.substr(len-i, i);
DFs(s1, flag);
//递归结束后,弹出push入的元素
nums.pop_back();
}
}
}
vector<vector<string>> partition(string s) {
DFs(s, false);
return sums;
}
};
解题感悟
对于该类题目,其实我刚开始做的时候也并非一帆风顺,刚开始递归时就是出现种类缺失、元素缺失等问题。。。大概率是自己水平有限,对递归理解不够透彻吧。当然经过调试、看代码理清结构后,才写出通过的代码。相比较官方的代码感觉自己的很low,当然自己做出来的,心情还是很不错的。加油!