動態規劃求最長迴文子序列
阿新 • • 發佈:2019-02-16
題目
找出字串中最長迴文子序列,可以在原字串中不連續。
如“character”的最長迴文子序列為“carac”。
分析1
設字串
基本情況是
當
當 i
程式碼1
import java.util.ArrayList;
import java.util.List;
public class Main {
static void palindrome(String[] s, int[][] p, String[][] so) {
int n = s.length;
for (int i = 0; i < n; i++) {
p[i][i] = 1;
}
for (int l = 2; l <= n; l++) {
for (int i = 0; i < n - l + 1; i++) {
int j = i + l - 1;
if (!s[i].equals(s[j])) {
if (p[i][j - 1] > p[i + 1][j]) {
p[i][j] = p[i][j - 1];
so[i][j] = "left";
} else {
p[i][j] = p[i + 1][j];
so[i][j] = "down";
}
} else {
p[i][j] = p[i + 1][j - 1] + 2;
so[i][j] = "leftdown";
}
}
}
}
static void solution(String[] s, String[][] so, int i, int j, List<String> result) {
if (i >= s.length || j <= 0) return;
if (i == j) {
result.add(result.size() / 2, s[i]);
return;
}
if ("leftdown".equals(so[i][j])) {
solution(s, so, i + 1, j - 1, result);
result.add(0, s[i]);
result.add(result.size(), s[i]);
} else if ("left".equals(so[i][j])) {
solution(s, so, i, j - 1, result);
} else {
solution(s, so, i + 1, j, result);
}
}
public static void main(String[] args) {
String str = "character";
String[] s = str.split("");
int n = s.length;
int[][] p = new int[n][n];
String[][] so = new String[n][n];
palindrome(s, p, so);
System.out.println(p[0][n - 1]);
List<String> result = new ArrayList<>();
solution(s, so, 0, n - 1, result);
System.out.println(result);
}
}
分析2
一個字串的最長迴文子序列就是這個字串和其逆序串的最長公共子序列,這樣就可以將問題轉化。設字串
程式碼2
import java.util.ArrayList;
import java.util.List;
public class Main {
static void LCS(String[] X, String[] Y, int[][] p, String[][] so) {
int nX = X.length;
int nY = Y.length;
for (int i = 0; i < nX + 1; i++) {
p[i][0] = 0;
}
for (int i = 0; i < nY + 1; i++) {
p[0][i] = 0;
}
for (int i = 1; i <= nX; i++) {
for (int j = 1; j <= nY; j++) {
if (X[i - 1].equals(Y[j - 1])) {
p[i][j] = p[i - 1][j - 1] + 1;
so[i][j] = "leftup";
} else if (p[i - 1][j] >= p[i][j - 1]) {
p[i][j] = p[i - 1][j];
so[i][j] = "up";
} else {
p[i][j] = p[i][j - 1];
so[i][j] = "left";
}
}
}
}
static void solution(String[] X, String[][] so, int i, int j, List<String> result) {
if (i == 0 || j == 0) {
return;
}
if (so[i][j].equals("leftup")) {
solution(X, so, i - 1, j - 1, result);
result.add(X[i - 1]);
} else if (so[i][j].equals("up")) {
solution(X, so, i - 1, j, result);
} else {
solution(X, so, i, j - 1, result);
}
}
public static void main(String[] args) {
String str = "character";
String restr = new StringBuilder(str).reverse().toString();
String[] X = str.split("");
String[] Y = restr.split("");
int n = X.length;
int[][] p = new int[n + 1][n + 1];
String[][] so = new String[n + 1][n + 1];
LCS(X, Y, p, so);
System.out.println(p[n][n]);
List<String> result = new ArrayList<>();
solution(X, so, n, n, result);
System.out.println(result);
}
}