
本文共 1450 字,大约阅读时间需要 4 分钟。
题目:
Given a string s, find the longest palindromic subsequence's length in s. You may assume that the maximum length of s is 1000.
Example 1:
Input:"bbbab"
Output:
4
One possible longest palindromic subsequence is "bbbb".
Example 2:
Input:"cbbd"
Output:
2
One possible longest palindromic subsequence is "bb".
Constraints:
1 <= s.length <= 1000
s
consists only of lowercase English letters.
思路:
找最长回文子序列。这是一道标准区间型DP,有一些经典的细节要点。首先,二维数组的大小是n+1或者n都行,此处假设使用n。那么dp[i][j]代表的就是第i的字母到第j个字母间的最大回文长度。以此为考虑,初始化显然所有dp[i][i]都应该是1,因为单字母本身就形成长度为1的最小回文。然后是区间型DP,我们已经考虑过长度为1的情况,因此这个区间长度显然是从len=2开始的。然后是确定i和j,i的范围显然可以从0到n-len,这里能够到n-len这个位置,比如一个长为6的字符串,len为2,那么i的范围就应该是[0, 4],因为从substring看,4+2-1=5,极为字符串的最后一个index。在确定i以后,j即为i+len-1,找出从i开始长度为len的字符串的结尾下标即是j。
之后对于dp[i][j],分情况讨论:
首先dp[i][j]原本等于1,因此dp[i][j]只能从dp[i+1][j]或者dp[i][j-1]来,假设字符串“a[bsass]f”,i和j是左右括号,并不真实存在,那么从左到右既然s[i]='b', s[j]='s',并不相同,则dp[i][j]只能从dp[i+1][j],即"sass"或者dp[i][j-1],即“bsas”中挑选最大的。
如果s[i]==s[j],则dp[i][j]可以从dp[i][j]上面比较完的本身,或者dp[i+1][j-1]得来。假设字符串“asb[abccba]sdasd”,此时s[i]==s[j]=='a',则我们已知"bccb"的值,即dp[i+1][j-1],再次基础上+2即可,因为头尾两个字符。
综上所述,转移方程为:
代码:
class Solution {
public: int longestPalindromeSubseq(string s) { int n=s.size(); vector<vector<int>> dp(n,vector<int>(n)); for(int i=0;i<n;i++) dp[i][i]=1; for(int len=2;len<=n;len++) { for(int i=0;i<=n-len;i++) { int j=i+len-1; dp[i][j]=max(dp[i][j-1],dp[i+1][j]); if(s[i]==s[j]) dp[i][j]=max(dp[i][j],dp[i+1][j-1]+2); } } return dp[0][n-1]; } };发表评论
最新留言
关于作者
