最长公共子序列的最大长度
/**
* 最长公共子序列的长度
* 题目描述
* 给定2个无序序列 s1 s2, 求2个字符串的最长公共子序列,子序列的元素都得在s1,s2中找到,并且与s1 s2 的顺序相同
* 解题思路:
* 动态规划
* 对s1左边的i个和s2左边的j个字符分别讨论,求它们能够组成的最长公共子序列的长度,因为涉及到2个自变量,所以应该维护一个二维数组maxLen[i][j]
* 那么怎么求maxLen[i][j]就是关键,需要求得其递推公式:maxLen[i][j]状态与它的前面的状态的关系,才能使用循环分别讨论i j
* maxLen[0][j] = 0
* maxLen[i][0] = 0
* maxLen[i][j] =
* {
* 1) maxLen[i-1][j-1]+1 (s1[i-1] == s2[j-1]) 字符串最左边的字符是s[0]
* 2) Max{maxLen[i][j-1], maxLen[i-1][j]} (s1[i-1] != s2[j-1])
* }
*/
package dp;
import java.util.LinkedList;
import java.util.Queue;
import java.util.Scanner;
public class Main {
static char[] c1 = null;
static char[] c2 = null;
static int[][] maxLen = null;
public static void main(String[] args){
/**
* 测试结果
* 输入:
* abcfbc abfcab
* 输出:
4
输入:
programming contest
输出:
2
输入:
abcd mnp
输出:
0
*/
Scanner in = new Scanner(System.in);
while(in.hasNext()){
c1 = in.next().toCharArray();
c2 = in.next().toCharArray();
//动态规划的二维数组申请空间
maxLen = new int[c1.length+1][c2.length+1];
//初始化边界条件
for(int j = 1; j <= c2.length; j++){
maxLen[0][j] = 0;
}
for(int i = 1; i <= c1.length; i++){
maxLen[i][0] = 0;
}
//分别讨论s1的左边i个,s2的左边j个 能组成的最长公共子序列的长度maxLen[i][j],使用递推公式循环处理
for(int i = 1; i <= c1.length; i++){//s1的左边i个
for(int j = 1; j <= c2.length; j++){//s2的左边j个
if(c1[i-1] == c2[j-1])
maxLen[i][j] = maxLen[i-1][j-1] + 1; //意味着s1[i] s2[j]同时为最长公共子序列的最后一个已经确定,那么当前状态可有前一状态maxLen[i-1][j-1]加上1求出
else
maxLen[i][j] = Math.max(maxLen[i][j-1], maxLen[i-1][j]);//意味着s[i]与s[j]至少有一个不是最长公共子序列的最后一个字符,那么可以选择性的干掉其中一个,
//得到前一状态,再由前边的状态的最大情况推出当前状态
}
}
System.out.println(maxLen[c1.length][c2.length]);
}
}
}