LCS问题,JAVA实现

本文参照July的博客,第十一章,只给出个人理解和java实现,问题说明略。

1. 穷举

如果X{1,2,3,4...m}

      y{1,2,3,4,..n}

那么 x的所有子序列, 2^m  ,  y的所有子序列, 2^n,穷举的时间复杂度 O(2^(m+n))

2. 果然动态规划其实才是重点。

   此题的重点在于反证法的使用,但是个人感觉是,除非是自己推出来,否则,总是会忘记。

  反证法和定尾点是解决关键。

  目前要求 xm 和 yn的最长公共子序列,那么定义一个数据结构,xi 和 yj的最长公共子序列  c[i,j]

  然后给出递归式子,要么加1,要么继承,

图片来自 july的文章

这个基本不考数据结构,就考算法

参考 算法给出java代码

import java.util.Arrays;


public class LCS {
	public static void main(String[] args) {
		char[] X = {'1','A','B','C','B','D','A','B'};
		char[] Y = {'2','B','D','C','A','B','A'};
		
		LCS_LENGTH(X,Y);
		
	}
	
	
	static void LCS_LENGTH(char[] X,char[] Y){
		
		int lenOfX = X.length;
		int lenOfY = Y.length;

		// 存储记录长度
		int[][] c = new int[lenOfX][lenOfY];
		// c是由哪一个记录到达的
		int[][] b = new int[lenOfX][lenOfY];
		
		for(int i=1;i<lenOfX;i++) c[i][0] = 0;
		for(int j=1;j<lenOfY;j++) c[0][j] = 0;
		for(int i=1;i<lenOfX;i++){
			for(int j=1;j<lenOfY;j++){
				if(X[i]==Y[j]){
					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{
					c[i][j]=c[i][j-1];
					b[i][j]= 3;// "←"
				}
			}
		}
		
//		System.out.println(Arrays.deepToString(b));
		LCS(b,X,lenOfX-1,lenOfY-1);
	}
	
	static void LCS(int[][] b, char[] X,int i , int j){
		if(i==0 || j==0) return;
		if(b[i][j]==1){
			LCS(b,X,i-1,j-1);
			System.out.print(X[i]);
		}
		else if(b[i][j] == 2) LCS(b,X,i-1,j);
		else LCS(b,X,i,j-1);
	}
}

可能是因为水平低,对此类算法题目无感,既无使用太多的数据结构,也不考验编程能力,只是抽象,非常抽象,适合数学专业出生的同学,工程师只是负责去实现。


第五节的改进算法确实很精彩,下面详细看一看。

今天状态很差,姑且做一次搬运工,刘佳梅女士的解法

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章