原题
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”.
Reference Answer
思路分析
-
思路
-
相比最长回文子串,最长回文子序列更像最长公共子序列,只是改变了循环方向
-
DP 定义
- 记
s[i:j] := 字符串 s 在区间 [i:j] 上的子串
- 定义
dp[i][j] := s[i:j] 上回文序列的长度
- 记
-
DP 初始化
dp[i][i] = 1 // 单个字符也是一个回文序列
-
DP 更新
dp[i][j] = dp[i+1][j-1] + 2, if s[i] == s[j] = max(dp[i+1][j], dp[i][j-1]), else
-
Python Version
class Solution:
def longestPalindromeSubseq(self, s: str) -> int:
if not s:
return 0
length = len(s)
dp = [[0]*length for _ in range(length)]
for i in range(length):
dp[i][i] = 1
for j in range(1, length):
for i in range(j)[::-1]:
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][length-1]
C++ version
class Solution {
public:
int longestPalindromeSubseq(string s) {
int length = s.length();
vector<vector<int>> dp(length, vector<int>(length, 0));
for (int i = 0; i < length; ++i){
dp[i][i] = 1;
}
for (int j = 1; j < length; ++j){
for (int i = j - 1; i >= 0; --i){
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][length-1];
}
};
Note
- Python 二维列表创建:
dp = [[0]*length for _ in range(length)]
- C++ 二维数组创建:
vector<vector<int>> dp(length, vector<int>(length, 0));