/**
* Longest Common Subsequence
*
* f(i, j) = max{f(i-1, j-1), f(i-1, j-1)+1, f(i-1, j), f(i, j-1)}
*
* 主要在空间优化,逐行扫描,下一行只依赖与上一行和本行,可以只需要定义2个数组,更好的办法只需要一个数组
* 每次计算出一个新值,先不更新,等下一个求出来之后,再更新前一个。
* O(min{m, n}+1)
*
*/
public class LCS {
public static int lcs(int[] a, int[] b){
assert(true);
int[][] v = new int[a.length+1][b.length+1];
for(int i=1; i<=a.length; i++){
for(int j=1; j<=b.length; j++){
int max = v[i-1][j-1];
if(a[i-1] == b[j-1]){
max++;
}
int max2 = v[i-1][j] > v[i][j-1] ? v[i-1][j] : v[i][j-1];
v[i][j] = max > max2 ? max : max2;
}
}
return v[a.length][b.length];
}
public static int lcs2(int[] a, int[] b){
int longLength = a.length;
int shortLength = b.length;
int[] longArray = a;
int[] shortArray = b;
if(a.length < b.length){
longLength = b.length;
shortLength = a.length;
longArray = b;
shortArray = a;
}
int[] v = new int[shortLength+1];
for(int i=1; i<=longLength; i++){
int pre = 0;
for(int j=1; j<=shortLength; j++){
int max = v[j-1];
if(longArray[i-1] == shortArray[j-1]){
max++;
}
int max2 = pre>v[j] ? pre : v[j];
v[j-1] = pre;
pre = max>max2 ? max : max2;
}
v[shortLength] = pre;
}
return v[shortLength];
}
/**
* @param args
*/
public static void main(String[] args) {
int[] a = {1, 3, 9, 6, 2,4,7,5};
int[] b = {7,2,4,8,3,5,1,9,0,6};
int max = LCS.lcs(a, b);
int max2 = LCS.lcs2(a, b);
System.out.println(max);
System.out.println(max2);
}
}最长公共子序列
最新推荐文章于 2025-05-24 12:00:00 发布
29万+

被折叠的 条评论
为什么被折叠?



