(1)问题描述
求俩个数组S1和S2的最长公子序列。
(2)基本思路
(3)代码实现
public class fuck {
public static void main(String[] args) {
char []x = {'A','B','C','B','D','A','B'};
char []y = {'B','D','C','A','B','A'};
int [][]b = new int[x.length+1][y.length+1];
int lcslength = lcsLength(x,y,b);
System.out.println(lcslength);
String s="";
lcs(x.length,y.length,x,b,lcslength,s);
}
/*
* 返回数组x和数组y最长公子序列的长度
* 1 二维数组b是为了lcs方法的输入而弄的一个表
*/
public static int lcsLength(char []x,char []y,int [][] b) {
int m = x.length;
int n = y.length;
int c[][] =new int[x.length+1][y.length+1];
for(int i =0;i<=m;i++) {
c[i][0]=0;
}
for(int i=0;i<=n;i++) {
c[0][i]=0;
}
for(int i=1;i<=m;i++) {
for(int j=1;j<=n;j++) {
if(x[i-1]==y[j-1]) { //由于c数组比x和y数组左右都大一层
c[i][j]=c[i-1][j-1]+1;
b[i][j]=1;
}
else {
if(c[i-1][j]>c[i][j-1]) {
c[i][j]=c[i-1][j];
b[i][j]=2;
}else if(c[i-1][j]<c[i][j-1]) {
c[i][j]=c[i][j-1];
b[i][j]=3;
}else if(c[i-1][j]==c[i][j-1] ) {
c[i][j]=c[i-1][j];
b[i][j]=4;
}
}
}
}
return c[m][n];
}
/*
* 打印出最长公子序列
*/
public static void lcs(int m1,int n1,char []x1,int [][]b1,int max,String s) {
if(m1==0 || n1==0) { //将s里的字符串进行转置
StringBuilder sb = new StringBuilder(s);
s = sb.reverse().toString();
if(s.length()==max) //再次确定是否是最大的公子序列
System.out.println(s);
}else {
if(b1[m1][n1]==1) {
s=s+x1[m1-1];
lcs(m1-1,n1-1,x1,b1,max,s);
}else if(b1[m1][n1]==2){
lcs(m1-1,n1,x1,b1,max,s);
}else if(b1[m1][n1]==3) {
lcs(m1,n1-1,x1,b1,max,s);
}else if(b1[m1][n1]==4) {
lcs(m1-1,n1,x1,b1,max,s); //进行分支
//思想是把东西丢进去而不是从底层递归出来
lcs(m1,n1-1,x1,b1,max,s);
}
}
}
}
4
BCBA
BCAB
BDAB
(4)时间复杂度和空间复杂度
时间复杂度:
O(mn)
空间复杂度:
O(mn)