题目
516. 最长回文子序列
给你一个字符串 s ,找出其中最长的回文子序列,并返回该序列的长度。
子序列定义为:不改变剩余字符顺序的情况下,删除某些字符或者不删除任何字符形成的一个序列。
示例 1:
输入:s = “bbbab”
输出:4
解释:一个可能的最长回文子序列为 “bbbb” 。
示例 2:
输入:s = “cbbd”
输出:2
解释:一个可能的最长回文子序列为 “bb” 。
思路
最值,动态规划安排上.(还不是背题吗)
备忘录数组 递归 or dp table 迭代
总结一下,就是dp[] dp[][] 一维二维的区别,根据条件分析出来+1 -1的规律.见多识广吧.继续
class Solution {
Integer[][] table;
public int longestPalindromeSubseq(String s) {
int n = s.length();
table = new Integer[n][n];
return dfs(s, 0, s.length() - 1);
}
private int dfs(String s, int start, int end) {
if (table[start][end] != null) {
return table[start][end];
}
int res = 0;
if (start == end) {
res = 1;
} else if (start > end) {
res = 0;
} else {
if (s.charAt(start) == s.charAt(end)) {
res = dfs(s, start + 1, end - 1) + 2;
} else {
res = Math.max(dfs(s, start + 1, end), dfs(s, start, end - 1));
}
}
table[start][end] = res;
return res;
}
}
方法二:
dp table
class Solution {
public int longestPalindromeSubseq(String s) {
int n = s.length();
int[][] dp = new int[n][n];
// dp[i][j] 代表 i 到 j 的最长回文长度
for (int i = 0;i < n;i++) {
dp[i][i] = 1;
}
for (int i = n - 1;i >= 0;i--) {
for (int j = i + 1;j < n;j++) {
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][n-1];
}
}