【leedcode】5. 最长回文子串

132 阅读1分钟

这是我参与8月更文挑战的第12天,活动详情查看:8月更文挑战

难度:中等

题目描述

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

示例 1:

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

示例 2:

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

示例 3:

输入:s = "a" 输出:"a"

示例 4:

输入:s = "ac" 输出:"a"  

提示:

1 <= s.length <= 1000 s 仅由数字和英文字母(大写和/或小写)组成

解题思路

动态规划 做的题多了思路基本都一样:

  • dp[i][j]表示s[i:j]是否为回文串

  • 如果s[i] == s[j],则dp[i][j] == dp[i+1][j-1]

  • 每次更新完dp[i][j]之后,更新max_len和start边界

  • len(s) < 2时必为回文串

  • dp[i][i]=True

class Solution:
    def longestPalindrome(self, s: str) -> str:
        # 动态规划,dp[i][j]表示s[i:j]是否为回文子串
        # 每次判断s[i][j]时更新maxlen=j-i+1和start=i
        # 边界,当j-i+1<2时,肯定是回文串
        n = len(s)
        dp = [[False]*n for _ in range(n)]
        start, lens = 0, 1

        # 边界
        if n < 2:
            return s
        # 初始化
        for i in range(n):
            dp[i][i] = True
        # 枚举区间终点
        for j in range(1, n):
            # 枚举起点
            for i in range(0, j):
                if s[i] == s[j]:
                    if j - i < 3:
                        dp[i][j] = True
                    else:
                        dp[i][j] = dp[i+1][j-1]
                
                if dp[i][j]:
                    l = j - i + 1
                    if l > lens:
                        lens = l
                        start = i

        return s[start: start+lens]

这道题看似麻烦,但仔细考虑回文子串只有两种情况奇偶回文( aba abba )

那么我们只需要循环字符串的每一个index,当满足一下条件时,从中心向两边扩展:

  1. left >= 0
  2. right < len(s)
  3. s[left] == s[right]

对于第三个条件,存在奇数回文和偶数回文的判断:

  • 奇数回文时,我们初始left == right
  • 偶数回文时,我们初始化right == left + 1
class Solution:
    def longestPalindrome(self, s):
        nums = len(s)
        # s为空或者s为自己本身的情况
        if nums < 2:
            return s
        ret = ''

        def finder(left, right):
            nonlocal ret
            while left >= 0 and right < nums and s[left] == s[right]:
                left -= 1
                right += 1
            ret = s[left + 1:right] if right - left - 1 > len(ret) else ret

        for i in range(nums ):
            finder(i, i)
            finder(i, i + 1)
        return ret