📜  最长回文序列(1)

📅  最后修改于: 2023-12-03 15:10:37.548000             🧑  作者: Mango

最长回文序列

简介

最长回文序列(Longest Palindromic Subsequence,LPS)问题是寻找一个给定字符串的最长回文子序列的问题。

回文串是指正反读都一样的字符串,而子序列是指从原字符串中去掉任意多个字符而不影响剩余字符相对位置得到的字符串。

解法
动态规划

最长回文序列可以用动态规划的方法来解决。设字符串为s,dp[i][j]表示s[i...j]的最长回文序列长度,则有:

  1. 当i=j时,dp[i][j]=1。
  2. 当s[i]=s[j]时,dp[i][j]=dp[i+1][j-1]+2。
  3. 当s[i]!=s[j]时,dp[i][j]=max(dp[i+1][j],dp[i][j-1])。
def longestPalindromeSubseq(s: str) -> int:
    n = len(s)
    dp = [[0] * n for _ in range(n)]
    for i in range(n-1, -1, -1):
        dp[i][i] = 1
        for j in range(i+1, n):
            if s[i] == s[j]:
                dp[i][j] = dp[i+1][j-1] + 2
            else:
                dp[i][j] = max(dp[i+1][j], dp[i][j-1])
    return dp[0][n-1]
中心扩展法

中心扩展法是一种从中心向两端扩展的方法,用于寻找回文串。具体地,对于每个中心点,向两端扩展,直到无法扩展为止,记录扩展长度,则可得到以该中心点为中心的最长回文序列长度。所有中心点的最长回文序列长度中的最大值即为整个字符串的最长回文序列长度。

def longestPalindromeSubseq(s: str) -> int:
    def expandAroundCenter(left, right):
        while left >= 0 and right < len(s) and s[left] == s[right]:
            left -= 1
            right += 1
        return (right - left - 2) // 2
    
    n = len(s)
    max_len = 0
    for i in range(n):
        len1 = expandAroundCenter(i, i)
        len2 = expandAroundCenter(i, i+1)
        max_len = max(max_len, len1, len2)
    return max_len + 1
性能

给定长度为n的字符串,动态规划解法的时间复杂度为O(n^2),空间复杂度为O(n^2);中心扩展法的时间复杂度为O(n^2),空间复杂度为O(1)。综合来看,中心扩展法更加简单高效,适合较短字符串的处理。