思路分析:
- 创建一个二维动态规划表
dp
,其中dp[i][j]
表示在子串s[i...j]
中的最长回文子序列的长度。 - 初始化基本情况:对角线上的元素
dp[i][i]
都为1,因为单个字符本身就是长度为1的回文子序列。 - 从字符串末尾向前遍历,填充动态规划表。对于每一对
(i, j)
,如果s[i]
等于s[j]
,则当前子串的最长回文子序列长度为dp[i + 1][j - 1] + 2
,否则取dp[i + 1][j]
和dp[i][j - 1]
中的较大值。 - 最终结果存储在
dp[0][s.size() - 1]
中,表示整个字符串s
的最长回文子序列的长度。
cpp
class Solution {
public:
// 计算最长回文子序列的长度
int longestPalindromeSubseq(string s) {
// 创建二维动态规划表,dp[i][j]表示子串s[i...j]的最长回文子序列长度
vector<vector<int>> dp(s.size(), vector<int>(s.size(), 0));
// 初始化基本情况:单个字符本身就是长度为1的回文子序列
for (int i = 0; i < s.size(); i++) {
dp[i][i] = 1;
}
// 自底向上填充动态规划表
// 从字符串末尾向前遍历
for (int i = s.size() - 1; i >= 0; i--) {
for (int j = i + 1; j < s.size(); j++) {
// 如果s[i]等于s[j],当前子串的最长回文子序列长度为dp[i + 1][j - 1] + 2
if (s[i] == s[j]) {
dp[i][j] = dp[i + 1][j - 1] + 2;
} else {
// 否则,取dp[i + 1][j]和dp[i][j - 1]中的较大值
dp[i][j] = max(dp[i + 1][j], dp[i][j - 1]);
}
}
}
// 最终结果存储在dp[0][s.size() - 1]中,表示整个字符串s的最长回文子序列长度
return dp[0][s.size() - 1];
}
};