每日一题--最长回文子串

353 阅读1分钟

这是我参与11月更文挑战的第22天,活动详情查看:[2021最后一次更文挑战]

题目

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

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

输入:s = "cbbd" 输出:"bb" 示例 3:

输入:s = "a" 输出:"a" 示例 4:

输入:s = "ac" 输出:"a"   提示: 1 <= s.length <= 1000 s 仅由数字和英文字母(大写和/或小写)组成

思路

中心扩散法怎么去找回文串? 从每一个位置出发,向两边扩散即可。遇到不是回文的时候结束。举个例子,str = acdbbdaastr=acdbbdaa 我们需要寻找从第一个 b(位置为 33)出发最长回文串为多少。怎么寻找? 首先往左寻找与当期位置相同的字符,直到遇到不相等为止。 然后往右寻找与当期位置相同的字符,直到遇到不相等为止。 最后左右双向扩散,直到左和右不相等。如下图所示:

每个位置向两边扩散都会出现一个窗口大小(len)。如果 len>maxLen(用来表示最长回文串的长度)。则更新 maxLen 的值。 因为我们最后要返回的是具体子串,而不是长度,因此,还需要记录一下 maxLen 时的起始位置(maxStart),即此时还要 maxStart=len。

代码

从每一个位置出发,向两边扩散即可。遇到不是回文的时候结束。举个例子,str = acdbbdaastr=acdbbdaa 我们需要寻找从第一个 b(位置为 33)出发最长回文串为多少。怎么寻找? 首先往左寻找与当期位置相同的字符,直到遇到不相等为止。 然后往右寻找与当期位置相同的字符,直到遇到不相等为止。

    console.log(s.length)
    if (s == null || s.length == 0) {
            return "";
        }
    let strLen = s.length;
    let left = 0;
    let len = 1
    let right = 0;
    let maxLen = 0;
    let maxStart = 0;
    for(let i = 0; i < strLen; i++) {
        left = i - 1;
        right = i + 1;
        while(s[left] === s[i] && left >= 0) {
            len++;
            left--
        }
        while(s[right] === s[i] && right< strLen) {
            len++;
            right++
        }
        while(left >= 0 && right < strLen && s[left] === s[right]) {
            len = len + 2;
            left--;
            right++
        }
        console.log(len)
        if (len > maxLen) {
                maxLen = len;
                maxStart = left;
            }
            len = 1;
    }
    return s.substring(maxStart + 1, maxStart + maxLen + 1);

};