Time: 20190906
Type: Medium
题目描述
给定一个字符串s,找到其中最长的回文子序列。可以假设s的最大长度为1000。
示例 1:
输入:
“bbbab”
输出:
4
一个可能的最长回文子序列为 “bbbb”。
示例 2:
输入:
“cbbd”
输出:
2
一个可能的最长回文子序列为 “bb”。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/longest-palindromic-subsequence
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
思路
从“最长”这个关键词可以推导出用动态规划算法。
状态定义
定义f[i][j]
表示表示[i...j]
子字符串最长回文子序列的长度。
状态转移方程
按照当前字符是否相等划分为两个类别:
s[i] == s[j]
⇒f[i][j] = f[i+1][j-1] + 2
s[i] != s[j]
⇒f[i][j] = max(f[i+1][j], f[i][j-1])
注意i左边比右边小,因此是从大到小遍历。f[i][i] = 1
,表示初始状态,单个字符的最长回文子序列为1。
代码
class Solution:
def longestPalindromeSubseq(self, s: str) -> int:
# f[i][j]表示[i...j]字符串最长回文子序列的长度
n = len(s)
f = [[0] * n for _ in range(n)]
# f[i][j] = f[i+1][j-1] + 2, s[i] == s[j]
# f[i][j] = max(f[i+1][j], f[i][j-1]), s[i] != s[j]
# i从大到小,j从小到大
for i in range(n-1, -1, -1):
f[i][i] = 1
for j in range(i + 1, n):
if s[i] == s[j]:
f[i][j] = f[i+1][j-1] + 2
else:
f[i][j] = max(f[i+1][j], f[i][j-1])
return f[0][n-1]
END.