import com.sun.org.apache.regexp.internal.RE;
import java.sql.PreparedStatement;
public class Main {
public static void main(String[] args) {
Main main = new Main();
char[] A = "ABCBDAB".toCharArray();
char[] B = "BDCABA".toCharArray();
main.LCS_LENGTH(A,B);
System.out.println();
int[] NUM = {10,9,2,5,3,7,101,18};
main.MONOTONE_INCREASING(NUM);
main.MONOTONE_INCREASING_OPTIMAL(NUM);
}
//自底向上
public void LCS_LENGTH(char[] X, char[] Y) {
int m = X.length;
int n = Y.length;
char[][] b = new char[m + 1][n + 1];
int[][] c = new int[m + 1][n + 1];
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
if (X[i]==Y[j]){
c[i + 1][j + 1] = c[i][j] + 1;
b[i+1][j+1]='↖';
} else if (c[i][j + 1] < c[i + 1][j]) {
c[i + 1][j + 1] = c[i + 1][j];
b[i + 1][j + 1] = '←';
}else {
c[i + 1][j + 1] = c[i][j + 1];
b[i + 1][j + 1] = '↑';
}
System.out.print(b[i + 1][j + 1]);
}
System.out.println();
}
System.out.println("最长公共子序列长度为:"+c[m][n]);
System.out.print("最长公共子序列为:");
PRINT_LCS(b,X,m,n);
}
//带备忘录
public int LCS_LENGTH_MEMORIZED(char[] X, char[] Y,int c[][],char b[][],int i,int j) {
if (i == 0 || j == 0) {
PRINT_LCS(b, X, X.length + 1, Y.length + 1);
}
if (X[i] == Y[j]) {
return c[i + 1][j + 1] = LCS_LENGTH_MEMORIZED(X, Y, c, b, i-1, j-1);
}else return c[i + 1][j + 1] = Math.max(LCS_LENGTH_MEMORIZED(X, Y, c, b, i-1, j),LCS_LENGTH_MEMORIZED(X, Y, c, b, i, j-1));
}
//打印结果
public void PRINT_LCS(char[][] b, char[] X, int i, int j) {
if (i==0||j==0) return;
// if(X[i]==X[j]){ 15.4-2习题
if (b[i][j]=='↖'){
PRINT_LCS(b, X, i - 1, j - 1);
System.out.print(X[i-1]);
} else if (b[i][j] == '↑') {
PRINT_LCS(b,X,i-1,j);
}else PRINT_LCS(b,X,i,j-1);
}
//练习14.4-5 O(n2)的单调递增子序列
public void MONOTONE_INCREASING(int[] NUM) {
if (NUM.length==0) return;
int RES=1;
int c[] = new int[NUM.length];
for (int i=0;i<c.length; i++) { c[i]=1; }
for (int i = 1; i < NUM.length; i++) {
int curr=1;
for (int j = i - 1; j >= 0; j--) {
if (NUM[j] < NUM[i]) {
curr = curr > 1 + c[j] ? curr : 1 + c[j];
}
}
c[i] = curr;
RES = RES > c[i] ? RES : curr;
}
System.out.println(RES);
}
//练习14.4-6 O(nlgn)最长单调子序列int[] NUM = {5, 6, 1, 3, 4, 9, 1, 6, 5, 6};
public void MONOTONE_INCREASING_OPTIMAL(int[] NUM) {
int len = 1, n = NUM.length;
if (n == 0) return ;
int[] d = new int[n + 1];
for (int i = 1; i < n; ++i) {
if (NUM[i] > d[len]) d[++len] = NUM[i];
else{
int l = 1, r = len, pos = 0; // 如果找不到说明所有的数都比 nums[i] 大,此时要更新 d[1],所以这里将 pos 设为 0
while (l <= r) {
int mid = (l + r) >> 1;
if (d[mid] < NUM[i]) {
pos = mid;
l = mid + 1;
}
else r = mid - 1;
}
d[pos + 1] = NUM[i];
}
}
System.out.println(len);
return ;
}
}
算法导论:最长公共子序列问题(动态规划+贪心+二分查找)
最新推荐文章于 2023-06-29 00:49:57 发布