代码随想录第二十七天 | 131.分割回文串

89 阅读2分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第1天,点击查看活动详情

131.分割回文串

题目分析

题目给出一个字符串,要求将字符串分割成每个子串都是回文串的子串。返回所有可能的分割方案。

“回文串”是一个正读和反读都一样的字符串,比如“level”或者“noon”等等就是回文串。

也就是说这道题要求在分割子串的同时判断回文串。

解题

这道题主要解决的问题是切割以及判断回文。

如果想使用暴力的方法解决for循环很难解决,但是我们刚刚学习了组合问题的解决方案。分割问题从根本上与组合问题有一些相似之处,我们可以将解决组合问题的思路代入分割问题。

对于分割问题也可以抽象为一棵树形结构。

image.png

通过for循环横向遍历,通过递归纵向遍历。最后得出想要的分割方案。

仍然是回溯三部曲:

  1. 递归函数的参数

首先是整个字符串s,然后是切割字符串的范围。

  1. 回溯函数终止条件

当递归到叶子节点的时候,也就是切割字符串时到末尾的时候,可以结束回溯,将结果放入结果数组中。

  1. 单层搜索的过程

判断子串是否为回文串,如果是回文就加入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()
        }
    }
};

判断回文串

我们可以通过双指针的方式判断字符串是否为回文串。一个指针从前向后,一个指针从后向前,如果前后指针所指元素相同就是回文字符串。这个判断还是很简单的。