📜  门| GATE-CS-2014-(Set-1) |问题 13(1)

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

问题13

本题涉及以下概念:字符串,数组,动态规划。

给定长度为n的字符串s,求其中最长的回文子序列。回文子序列指的是正着读和倒着读都一样的子序列。

例如,字符串s="BBABCBCAB",则其中最长的回文子序列为"BBCBB"或"BCBCB"。

解法

这是一道典型的动态规划问题。记dp[i][j]表示s[i...j]中最长的回文子序列长度。

我们可以考虑dp[i][j]的初始值,显然当i=j时dp[i][j]=1,因为一个字符本身就是一个回文。

对于其他情况,我们需要分别考虑两种情况,即当前字符串的首尾字符相等或不相等。

当s[i]=s[j]时,我们可以将这两个字符都加入回文子序列中,此时dp[i][j]=dp[i+1][j-1]+2。

当s[i]!=s[j]时,我们不能同时保留这两个字符,因此我们需要分别考虑删除i或j哪一个字符。具体来说,我们可以比较dp[i+1][j]和dp[i][j-1],取其中较大的一个作为dp[i][j]的值。

最终答案即为dp[0][n-1],即整个字符串的最长回文子序列。

代码实现如下:

def longest_palindrome_subsequence(s):
    n = len(s)
    dp = [[0]*n for _ in range(n)]
    for i in range(n):
        dp[i][i] = 1
    for i in range(n-1, -1, -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]

该算法的时间复杂度为O(n^2),空间复杂度为O(n^2)。