LeetCode-最长回文子串

778 阅读2分钟

「这是我参与2022首次更文挑战的第23天,活动详情查看:2022首次更文挑战

Hope is a good thing, maybe the best of things. And no good thing ever dies—— 《The Shawshank Redemption》

题目

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

示例 1:

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

示例 2:

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

来源:力扣(LeetCode)

题目分析

中心扩散法

  1. 分析
  • 对于字符串来说,每一个字符都可以作为回文串的中心点(回文串的中心点的意思是从中间向两边扩散开来)
  • 既然每个一字符都可以作为回文串的中心点,回文串又有奇数回文串和偶数回文串
  • 遍历字符串的每个字符,分别对奇数回文串和偶数回文串取最长的
  1. 代码实现
/**
 * @param {string} s
 * @return {number}
 */
var longestPalindrome = function (s) {
  // 思路:从中间开始向两边扩散来判断回文串
  /**
   *
   * @param {*} s
   * @param {*} l 左边界
   * @param {*} r 右边界
   */
  let palindrome = (s, l, r) => {
    while (l >= 0 && r < s.length && s[l] == s[r]) {
      // 向两边展开
      l--;
      r++;
    }
    // 返回以s[l]和s[r]为中心的最长回文串
    return s.substr(l + 1, r - l - 1);
  };
  let res = "";
  for (let i = 0; i < s.length; i++) {
    // 以s[i]为中心的最长回文串
    let s1 = palindrome(s, i, i);
    // 以s[i]和s[i+1]为中心的最长回文串
    let s2 = palindrome(s, i, i + 1);
    res = res.length > s1.length ? res : s1;
    res = res.length > s2.length ? res : s2;
  }
  return res;
};

  1. 复杂度分析 时间复杂度:O(n^2),空间复杂度:O(1)。

左右指针

  1. 分析 如果是回文子串,那么它的左右两边的元素肯定是对称的,我们可以使用左右指针,从当前元素向两边扩散,以找到最长字串。

  2. 代码实现

function longestPalindrome(s: string): string {
    let res = '';
    for (let i = 0; i < s.length; i++) {
        // 寻找长度为奇数的回文子串(以当前元素向两边扩散)
        const s1 = palindrome(s, i, i);
        // 寻找长度为偶数的回文子串(以s[i],s[i + 1])向两边扩散
        const s2 = palindrome(s, i, i + 1);
        res = res.length > s1.length ? res : s1;
        res = res.length > s2.length ? res : s2;
    }
    return res;
};

function palindrome(s, l, r) {
    // 左右指针,从s[l]和s[r]向两边扩散,找到最长回文串
    while (l >= 0 && r < s.length && s[l] == s[r]) {
        l--; r++;
    }
    return s.substr(l + 1, r - l - 1);
}

  1. 复杂度分析

时间复杂度:O(n^2), 空间复杂度O(1)。

结语

如果这篇文章帮到了你,欢迎点赞👍和关注⭐️。

文章如有错误之处,希望在评论区指正🙏🙏

欢迎关注我的微信公众号,一起交流技术,微信搜索 🔍 :「 五十年以后