516.最长回文子序列
题目
516. 最长回文子序列 - 力扣(LeetCode) (leetcode-cn.com)
给你一个字符串 s
,找出其中最长的回文子序列,并返回该序列的长度。
子序列定义为:不改变剩余字符顺序的情况下,删除某些字符或者不删除任何字符形成的一个序列.
实例1:
输入:s = “bbbab”
输出:4
解释:一个可能的最长回文子序列为 “bbbb” 。
示例 2:
输入:s = “cbbd”
输出:2
解释:一个可能的最长回文子序列为 “bb” 。
思路
马拉车
马拉车算法用来解决最长回文字串的问题是最先想到的思路,但是本地比较特殊的一点在于,可以删除。如果分别删除,复杂度会太大,因此排除使用马拉车算法的思路。
动态规划
设置数组
dp
,dp[i][j]
代表从s[i]
到s[j]
的最长回文字串长度。初始状态:
dp[i][i]=1
中间状态:对于任意
i,j 0<=i<j<n
,其中任意字串的长度都已经通过循环获得。这里让j
从0开始循环的,因此0~j-1
内的所有字串的最大回文长度都已经知道,从0~j
相当于在此基础上在最后一位上加上了s[j]
。令i
从j-1
开始向0
循环,这样整体的长度才是从小往大:如果
s[i]==s[j]
,那么就是i+1~j-1
内最大的回文字串长度加上2: 如果`s[i]==s[j]`但是`dp[i+1][j-1]`并不是从`i+1`开始到`j-1`结束的回文字串呢?没有关系,中间的可以都删除,因此只需要保存最长的长度即可。dp[i][j]=dp[i+1][j-1]+2
如果
s[i]!=s[j]
,那么只需要dp[i][j]
设置为i~j-1
和i+1~j
中的最长回文字串长度即可:dp[i][j]=max(dp[i][j-1],dp[i+1][j])
由于是从头往后开始遍历的,因此遍历到i
的时候再将dp[i][j]
设置为1
即可。
结果: dp[i][j]
代表从s[i]
到s[j]
的最长回文字串长度。因此s
从0
到n-1
的最长回文字串长度就是dp[0][n-1]
。
代码:
1 | class Solution { |