动态规划之最长回文串

最长回文子串

leetcode 5

在这里插入图片描述

若一个字符串是回文串,那么它的首尾元素应该相同,并且若该字符串的长度大于2,除去首尾元素后依然是回文串。

由此可得到判断是否是回文串的递推公式,P ( i , j ) P(i, j)P(i,j) 代表子串S i S_{i}SiS j S_{j}Sj是否是回文串:

P ( i , j ) = {  true,   如果子串  S i … S j  是回文串   false,   其它情况  P(i, j)= \begin{cases}\text { true, } & \text { 如果子串 } S_{i} \ldots S_{j} \text { 是回文串 } \\ \text { false, } & \text { 其它情况 }\end{cases}P(i,j)={ true,  false,  如果子串 SiSj 是回文串  其它情况 

当且仅当S i + 1 S_{i+1}Si+1S j − 1 S_{j-1}Sj1是回文串,即P ( i + 1 , j − 1 ) = t r u e P(i+1, j-1) =trueP(i+1,j1)=true,且S i = = S j S_{i}==S_{j}Si==Sj时,P ( i , j ) = t r u e P(i, j)=trueP(i,j)=true

P ( i , j ) = P ( i + 1 , j − 1 ) ∧ ( S i = = S j ) P(i, j)=P(i+1, j-1) \wedge\left(S_{i}==S_{j}\right)P(i,j)=P(i+1,j1)(Si==Sj)

对于所有是回文串的子串,记录其长度,选择最长的

代码如下:

class Solution:
    def longestPalindrome(self, s: str) -> str:
        # 字符串长度小于2,则整个字符串都是回文串
        n = len(s)
        if n < 2:
            return s
        
        begin = 0
        maxlen = 1  # 任意一个元素都是回文串
        
        # 初始化,dp[i][j]表示s[i]...s[j]的子串是否是回文串
        dp = [[False]*n for _ in range(n)]
        for i in range(n):
            dp[i][i] = True
            # 任意一个元素s[i]都是回文串

        # 递推,遍历所有开始结束位置i,j。并判断是否是回文串
        for j in range(1,n):
            for i in range(j):
                if s[i] != s[j]:
                    # 首尾元素不相同,肯定不是回文串
                    dp[i][j] = False
                else:
                    if j-i < 3:
                        dp[i][j] = True
                        # 首尾元素相同,剩余部分少于一个元素
                    else:
                        dp[i][j] = dp[i+1][j-1]
                if dp[i][j] and j - i + 1 > maxlen:
                    # 记录最长的回文串索引
                    maxlen = j - i + 1
                    begin = i
        return s[begin:begin+maxlen]

版权声明:本文为ltochange原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。