【leet-code清晰解题思路】5. 最长回文子串

67 阅读1分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第5天,[点击查看活动详情](juejin.cn/post/714765…

题目描述

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

示例 1:

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

示例 2:

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

提示:

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

解题思路

  • 子串就是截取字符串中的连续的一部分,我们可以暴力枚举每一个子串。通过两重for循环即可。对于回文串的验证,最简单的想法是可以从字符串两边一组组向里对比是否相同,如果没有不相同的说明是中心对称的,也就是是回文串。对于刚才的算法,遍历子串复杂度n^2,回文串复杂度n,整体时间复杂度为O(n^3)不满足题目的数据范围。
  • 下面我们换一种思路,每一个回文串有一个对称中心,以中心向外,两两相同。这样枚举中心复杂度为n,整体复杂度将为O(n^2)。这个方法可以称为中心扩散法。
func longestPalindrome(s string) string {
   l, r := 0, 0
   for i := 0; i < len(s); i++ {
      t := [][]int{{i - 1, i + 1}, {i, i + 1}}
      for _, xy := range t {
         x, y := xy[0], xy[1]
         for y < len(s) && x >= 0 && s[x] == s[y] {
            y++
            x--
         }
         if y-x-2 > r-l {
            l, r = x+1, y-1
         }
      }
   }
   return s[l : r+1]
}

image.png

  • 效果不错,但是有一个专业的算法马拉车,复杂度更低,回头再做介绍。

func longestPalindrome(s string) string {
   start, end := 0, -1
   t := "#"
   for i := 0; i < len(s); i++ {
      t += string(s[i]) + "#"
   }
   t += "#"
   s = t
   arm_len := []int{}
   right, j := -1, -1
   for i := 0; i < len(s); i++ {
      var cur_arm_len int
      if right >= i {
         i_sym := j * 2 - i
         min_arm_len := min(arm_len[i_sym], right-i)
         cur_arm_len = expand(s, i-min_arm_len, i+min_arm_len)
      } else {
         cur_arm_len = expand(s, i, i)
      }
      arm_len = append(arm_len, cur_arm_len)
      if i + cur_arm_len > right {
         j = i
         right = i + cur_arm_len
      }
      if cur_arm_len * 2 + 1 > end - start {
         start = i - cur_arm_len
         end = i + cur_arm_len
      }
   }
   ans := ""
   for i := start; i <= end; i++ {
      if s[i] != '#' {
         ans += string(s[i])
      }
   }
   return ans
}

func expand(s string, left, right int) int {
   for ; left >= 0 && right < len(s) && s[left] == s[right]; left, right = left-1, right+1 { }
   return (right - left - 2) / 2
}
  • 由于数据量太小,时间反而不尽人意,空间页消耗更多

image.png