开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第1天,点击查看活动详情
131.分割回文串
题目分析
题目给出一个字符串,要求将字符串分割成每个子串都是回文串的子串。返回所有可能的分割方案。
“回文串”是一个正读和反读都一样的字符串,比如“level”或者“noon”等等就是回文串。
也就是说这道题要求在分割子串的同时判断回文串。
解题
这道题主要解决的问题是切割以及判断回文。
如果想使用暴力的方法解决for循环很难解决,但是我们刚刚学习了组合问题的解决方案。分割问题从根本上与组合问题有一些相似之处,我们可以将解决组合问题的思路代入分割问题。
对于分割问题也可以抽象为一棵树形结构。
通过for循环横向遍历,通过递归纵向遍历。最后得出想要的分割方案。
仍然是回溯三部曲:
- 递归函数的参数
首先是整个字符串s,然后是切割字符串的范围。
- 回溯函数终止条件
当递归到叶子节点的时候,也就是切割字符串时到末尾的时候,可以结束回溯,将结果放入结果数组中。
- 单层搜索的过程
判断子串是否为回文串,如果是回文就加入path中。
代码如下:
const isPalindrom = (s,l,r) => {
for(let i = l,j = r;i < j;i++,j--) {
if(s[i] !== s[j]) return false
}
return true
}
var partition = function(s) {
const res = [],path = [],len = s.length
backstracking(0)
return res
function backstracking(i) {
if(i >=len) {
res.push(Array.from(path))
return
}
for(let j = i;j < len;j++) {
if(!isPalindrom(s,i,j)) continue
path.push(s.slice(i,j + 1))
backstracking(j + 1)
path.pop()
}
}
};
判断回文串
我们可以通过双指针的方式判断字符串是否为回文串。一个指针从前向后,一个指针从后向前,如果前后指针所指元素相同就是回文字符串。这个判断还是很简单的。