516. 最长回文子序列(Python)

题目

难度:★★★☆☆
类型:字符串
方法:动态规划

力扣链接请移步本题传送门
更多力扣中等题的解决方案请移步力扣中等题目录

给定一个字符串 s ,找到其中最长的回文子序列,并返回该序列的长度。可以假设 s 的最大长度为 1000 。

示例

示例 1:

输入:

"bbbab"
输出:

4
一个可能的最长回文子序列为 "bbbb"。

示例 2:

输入:

"cbbd"
输出:

2
一个可能的最长回文子序列为 "bb"。

提示:

1 <= s.length <= 1000
s 只包含小写英文字母

解答

这道题使用动态规划来做。

定义:设输入字符串s的长度为n,设dp矩阵为nxn维,dp[i][j]表示以下标i开始,以下标j结尾的子串中最长回文子序列的长度。i<=j
初始化:设置dp矩阵为对角阵,即对角线处的所有元素为1,其他元素填充为0,因为当i=j时,选中的子串只包含一个字符。
递推公式:分两种情况,
第一,从下标i+1到j-1的串左右两头均各增加一个字符,如果新增的两个字符一致,也就是s[i]==s[j],那么将从下标i+1到j-1的串对应的最长回文子序列的长度加2即可,也就是dp[i][j]=dp[i+1]dp[j-1]+2
第二,如果新增的两个字符不等,也就是s[i]!=s[j],那么选取dp[i+1][j]和dp[i][j-1]中更大的数作为dp[i][j]即可。
这里需要注意的是,为了保证每次递推都可以取到该有的值,外层遍历应该逆序,内层遍历应该顺序进行。
返回值:最终返回dp[0][n-1]即可。

class Solution:
    def longestPalindromeSubseq(self, s: str) -> int:
        n = len(s)
        dp = [[1 if i == j else 0 for i in range(n)] for j in range(n)]
        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]

如有疑问或建议,欢迎评论区留言~

有关更多力扣中等题的python解决方案,请移步力扣中等题解析

你可能感兴趣的:(516. 最长回文子序列(Python))