Leetcode——最长回文子序列
Posted Yawn,
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Leetcode——最长回文子序列相关的知识,希望对你有一定的参考价值。
1. 最长回文子序列
(1)动规
状态:
- dp[i][j] 表示 s 的第 i 个字符到第 j 个字符组成的子串中,最长的回文序列长度是多少。
转移方程:
- 如果 s 的第 i 个字符和第 j 个字符相同的话: dp[i][j] = dp[i + 1][j - 1] + 2
- 如果 s 的第 i 个字符和第 j 个字符不同的话: dp[i][j] = max(dp[i + 1][j], dp[i][j - 1])
- 然后注意遍历顺序,i 从最后一个字符开始往前遍历,j 从 i + 1 开始往后遍历,这样可以保证每个子问题都已经算好了。
- 从递推公式dp[i][j] = dp[i + 1][j - 1] + 2 和 dp[i][j] = max(dp[i + 1][j], dp[i][j - 1]) 可以看出,dp[i][j]是依赖于dp[i + 1][j - 1] 和 dp[i + 1][j],
- 如果我们想求dp[i][j],那么其他3个必须都是已知的,很明显从上往下遍历是不行的,我们只能让i从最后一个字符往前遍历,j从i的下一个开始遍历,最后只需要返回dp[0][length - 1]即可。
初始化:
- dp[i][i] = 1 单个字符的最长回文序列是 1
class Solution {
public int longestPalindromeSubseq(String s) {
int len = s.length();
int[][] dp = new int[len][len];
//这里i要从最后一个开始遍历
for(int i = len-1; i >= 0; --i) {
for(int j = i; j < len; ++j) {
//单个字符也是一个回文串
if(i == j) {
dp[i][j] = 1;
continue;
}
//j从i的下一个开始
if(s.charAt(i) == s.charAt(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][len-1];
}
}
以上是关于Leetcode——最长回文子序列的主要内容,如果未能解决你的问题,请参考以下文章