最长回文子串

83 阅读1分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第17天,点击查看活动详情

题目:

给你一个字符串 s,找到 s 中最长的回文子串。

示例 1:

输入:s = "babad" 输出:"bab" 解释:"aba" 同样是符合题意的答案。 示例 2:

输入:s = "cbbd" 输出:"bb"  

提示:

1 <= s.length <= 1000 s 仅由数字和英文字母组成

来源:力扣(LeetCode) 链接:leetcode.cn/problems/lo…

中心扩散法优化: 回文中心可以是多个相等的值

大体步骤:

次将每个数作为回文子串的中心,向两边扩散,若左/右的值和中心的值相等,则中心可能为多个相同的数(例如:"abccccba",回文中心为"cccc"),提前移动左/右到它与中心值不相等为止,然后再看是否还是回文串。

详细步骤:

一、1与2步骤是用来判断left与right是否与s[i]相等的,放在示例上说就是判断abccccba中cccc的过程,先找到中心的符号。

二 、找完中心(中心可以是1个或者多个字符),然后再开始左右扩大,判断左右指针对应的字符是否相等,如果相等同时将回文子串的长度+2。

三、每次都要更新一下目前的回文子串长度,以确保得到最长的回文子串。

四、由于题目要获得确切的子串,所以用到substring(startIndex,endIndex)方法截取出回文子串。

结束。

代码实现:

/**
 * @param {string} s
 * @return {string}
 */
var longestPalindrome = function (s) {
    let left, right, nowMax, len = s.length, maxLength = 0, maxStart;
    for (let i = 0; i < len; i++) {
        left = i - 1; //左指针起始位置
        right = i + 1; //右指针起始位置
        nowMax = 1; //初始回文子串长度为1,就是它自己
        // 判断中心符,abcccccba,中心可能为很多相同的字符
        //1.左指针与当前相等,左指针左移,回文子串长度加一
        while (left >= 0 && s[left] === s[i]) {
            left--;
            nowMax++;
        }
        //2.右指针与当前相等,右指针右移,回文子串长度加一
        while (right < len && s[right] === s[i]) {
            right++;
            nowMax++;
        }
        //确定完中心cccc后,再左右同时扩大更新回文子串长度
        //3.左右指针相等例如aabaa,则同时左右移动,回文子串长度加二
        while (left >= 0 && right < len && s[left] === s[right]) {
            left--;
            right++;
            nowMax += 2;
        }
        //更新目前最大的回文子串长度
        if (nowMax > maxLength) {
            maxLength = nowMax;
            //因为要得到回文子串,所以要获得子串起始位置的索引,也就是left
            maxStart = left;
        }
    }
    return s.substring(maxStart + 1, maxStart + 1 + maxLength)
}

好习惯的养成过程真奇妙,不知不觉,现在习惯了早睡早起,习惯每天有规律的刷刷算法,习惯看看JavaScript,我觉得很安逸,挺喜欢的。

带薪学习的生活今日就此结束啦。下次见。