0516. 最长回文子序列【中等】
1. 📝 题目描述
给你一个字符串 s,找出其中最长的回文子序列,并返回该序列的长度。
子序列定义为:不改变剩余字符顺序的情况下,删除某些字符或者不删除任何字符形成的一个序列。
示例 1:
txt
输入:s = "bbbab"
输出:4
解释:一个可能的最长回文子序列为 "bbbb"。1
2
3
2
3
示例 2:
txt
输入:s = "cbbd"
输出:2
解释:一个可能的最长回文子序列为 "bb"。1
2
3
2
3
提示:
1 <= s.length <= 1000s仅由小写英文字母组成
2. 🎯 s.1 - 区间 DP
c
int longestPalindromeSubseq(char* s) {
int n = strlen(s);
int** dp = (int**)malloc(sizeof(int*) * n);
for (int i = 0; i < n; i++) {
dp[i] = (int*)calloc(n, sizeof(int));
dp[i][i] = 1;
}
for (int i = n - 2; i >= 0; i--) {
for (int j = i + 1; j < n; j++) {
if (s[i] == s[j]) dp[i][j] = dp[i + 1][j - 1] + 2;
else dp[i][j] = dp[i + 1][j] > dp[i][j - 1] ? dp[i + 1][j] : dp[i][j - 1];
}
}
int res = dp[0][n - 1];
for (int i = 0; i < n; i++) free(dp[i]);
free(dp);
return res;
}1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
js
/**
* @param {string} s
* @return {number}
*/
var longestPalindromeSubseq = function (s) {
const n = s.length
const dp = Array.from({ length: n }, () => new Array(n).fill(0))
for (let i = n - 1; i >= 0; i--) {
dp[i][i] = 1
for (let j = i + 1; j < n; j++) {
if (s[i] === s[j]) dp[i][j] = dp[i + 1][j - 1] + 2
else dp[i][j] = Math.max(dp[i + 1][j], dp[i][j - 1])
}
}
return dp[0][n - 1]
}1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
py
class Solution:
def longestPalindromeSubseq(self, s: str) -> int:
n = len(s)
dp = [[0] * n for _ in range(n)]
for i in range(n - 1, -1, -1):
dp[i][i] = 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]1
2
3
4
5
6
7
8
9
10
11
12
2
3
4
5
6
7
8
9
10
11
12
- 时间复杂度:
- 空间复杂度:
算法思路:
dp[i][j]表示s[i..j]中最长回文子序列长度- 若
s[i] == s[j],则dp[i][j] = dp[i+1][j-1] + 2 - 否则
dp[i][j] = max(dp[i+1][j], dp[i][j-1])