Leetcode5 最长回文字符串

1,924 阅读2分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第13天,点击查看活动详情

前几天感冒,也没有学习。也不能全怪感冒,其实就是懒得学。。。不过,倒是把安排到五一的工作做完了

题目

给出字符串s,找出s中最长的回文字符串。

s = "babad" // 输出"bab", "aba"也同样符合;
s = "abb" // 输出"bb"

中心思想:扩散思维(利用for循环找出中心点,从中间向两边扩散。找到左右相同的最大字符串。)

题解

此题需要考虑到两种情况来找回文字符串的中心点。

1、有中心点

babaad: 此时可以以a为中心点向两边扩散找到bab,当然也可以以b为中心点找到aba;

2、无中心点

cabbad:这时字符串没有中心点,所以实际是在bb之间找到中心点向两边扩散找到abba;

在利用for循环找中心点时需要将以上两种情况都考虑到,以保证收录到所有可能构成回文子字符串的情况。

  • 代码思路

1、 如果字符串长度小于2,则直接返回该字符串;

2、定义两个变量:

start: 存储当前找到的最大回文字符串的起始位置;

maxLength: 记录当前回文字符串的长度;

start + maxLength: 回文字符串终止位置;

3、创建一个函数,判断是否同时满足以下三个条件:

① 判断左边是否出界;

② 判断右边是否出界;

③ 左边的字符是否等于右边的字符;

如果同时满足以上三个条件,则判断是否需要更i性能回文字符串的最大长度以及其实位置。

然后将left--,right++,继续做出判断直到不满足三个条件之一为止。

4、 遍历字符串寻找中心点时,每个位置都要调用两次上方的函数。第一遍检查i + 1i - 1,第二遍检查ii + 1。检查两遍是为了解决上述中有无中心点的两种情况。

代码实现

/**
 * @param {string} s
 * @return {string}
 */
var longestPalindrome = function(s) {
     if(s.length < 2) {
        return s;
    }
    let start = 0;
    let maxLength = 1; // 有情况为 s = "ab", 字符串不会为空

    function expendAroundCenter(left, right) {
        while(left >= 0 && right <= s.length && s[left] === s[right]) { // 三个边界条件判断
            if (right - left +1 > maxLength){ //right - left +1 可计算数组最大长度
                maxLength = right - left + 1; // 更新回文字符串的最大长度
                start = left; // 更新回文字符串的起始位置
            }
            left--; // 向左边扩散
            right++; // 向右边扩散
        }
    }

    for(let i = 0; i<s.length;i++) { // 循环找出中心点
        expendAroundCenter(i-1, i+1);  // 有中心点的情况
        expendAroundCenter(i, i+1); // 没有中心点的情况
    }
    return s.substring(start,start+maxLength)
};