pull/3/head
parent
8fdf1142f0
commit
598edb3a3a
@ -0,0 +1,113 @@
|
|||||||
|
package leo.class20;
|
||||||
|
|
||||||
|
import java.util.function.IntPredicate;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Leo
|
||||||
|
* @ClassName PalindromeSubsequence
|
||||||
|
* @DATE 2021/1/11 10:12 上午
|
||||||
|
* @Description 最长回文子序列
|
||||||
|
* https://leetcode-cn.com/problems/longest-palindromic-subsequence/
|
||||||
|
* 子序列可以不连续
|
||||||
|
* 子串必须连续
|
||||||
|
* 范围尝试模型特别在意开头和结尾.
|
||||||
|
*/
|
||||||
|
public class PalindromeSubsequence {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 一个字符串的逆序最长子序列,就是这个字符串的最长回文子序列
|
||||||
|
*/
|
||||||
|
static class Reverse {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static class Recursion {
|
||||||
|
public static int longestPalindromeSubseq(String s) {
|
||||||
|
if (s == null || s.length() == 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
char[] chars = s.toCharArray();
|
||||||
|
return f(chars, 0, chars.length - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 功能描述 : 求一个字符串从l到r范围中的最长回文子序列长度
|
||||||
|
* @author Leo
|
||||||
|
* @date 2021/1/11 10:21 上午
|
||||||
|
* @param str
|
||||||
|
* @param l
|
||||||
|
* @param r
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
public static int f(char[] str, int l, int r) {
|
||||||
|
if (l == r) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if (l == r - 1) {
|
||||||
|
return str[l] == str[r] ? 2 : 1;
|
||||||
|
}
|
||||||
|
int p1 = f(str, l + 1, r);
|
||||||
|
int p2 = f(str, l, r - 1);
|
||||||
|
int p3 = f(str, l + 1, r - 1);
|
||||||
|
int p4 = str[l] == str[r] ? (2 + f(str, l + 1, r - 1)) : 0;
|
||||||
|
return Math.max(Math.max(p1, p2), Math.max(p3, p4));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static class Dp {
|
||||||
|
public static int longestPalindromeSubseq(String s) {
|
||||||
|
if (s == null || s.length() == 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
char[] str = s.toCharArray();
|
||||||
|
int n = str.length;
|
||||||
|
int[][] dp = new int[n][n];
|
||||||
|
dp[n - 1][n - 1] = 1;
|
||||||
|
for (int i = 0; i < n - 1; i++) {
|
||||||
|
dp[i][i] = 1;
|
||||||
|
dp[i][i + 1] = str[i] == str[i + 1] ? 2 : 1;
|
||||||
|
}
|
||||||
|
//从底网上填
|
||||||
|
for (int l = n - 3; l >= 0; l--) {
|
||||||
|
for (int r = l + 2; r < n; r++) {
|
||||||
|
int p1 = dp[l + 1][r];
|
||||||
|
int p2 = dp[l][r - 1];
|
||||||
|
int p3 = dp[l + 1][r - 1];
|
||||||
|
int p4 = str[l] == str[r] ? (2 + dp[l + 1][r - 1]) : 0;
|
||||||
|
dp[l][r] = Math.max(Math.max(p1, p2), Math.max(p3, p4));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return dp[0][n - 1];
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int longestPalindromeSubseqMajorization(String s) {
|
||||||
|
if (s == null || s.length() == 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
char[] str = s.toCharArray();
|
||||||
|
int n = str.length;
|
||||||
|
int[][] dp = new int[n][n];
|
||||||
|
dp[n - 1][n - 1] = 1;
|
||||||
|
for (int i = 0; i < n - 1; i++) {
|
||||||
|
dp[i][i] = 1;
|
||||||
|
dp[i][i + 1] = str[i] == str[i + 1] ? 2 : 1;
|
||||||
|
}
|
||||||
|
//从底网上填
|
||||||
|
for (int l = n - 3; l >= 0; l--) {
|
||||||
|
for (int r = l + 2; r < n; r++) {
|
||||||
|
dp[l][r] = Math.max(dp[l][r - 1], dp[l + 1][r]);
|
||||||
|
if (str[l] == str[r]) {
|
||||||
|
dp[l][r] = Math.max(dp[l][r], 2 + dp[l + 1][r - 1]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return dp[0][n - 1];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static void main(String[] args){
|
||||||
|
int a = Dp.longestPalindromeSubseq("a");
|
||||||
|
System.out.println(a);
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in new issue