最长公共子序列属于动态规划中比较经典的题目,但是leetcode上好像没有这题,所以把这题的代码存放到简书。
LintCode本题链接
题目描述:给出两个字符串,找到最长公共子序列(LCS),返回LCS的长度。
说明
最长公共子序列的定义:
最长公共子序列问题是在一组序列(通常2个)中找到最长公共子序列(注意:不同于子串,LCS不需要是连续的子串)。该问题是典型的计算机科学问题,是文件差异比较程序的基础,在生物信息学中也有所应用。
维基百科关于LCS的介绍
样例
给出"ABCD" 和 "EDCA",这个LCS是 "A" (或 D或C),返回1
给出 "ABCD" 和 "EACB",这个LCS是"AC"返回 2
方法一 递归(超时)
public int longestCommonSubsequence(String str1,String str2){
return longestCommonSequence(str1,str1.length()-1,str2,str2.length()-1,0);
}
private int longestCommonSubsequence(String str1, int index1, String str2, int index2,int count){
if(index1<0||index2<0) return count;
if(str1.charAt(index1)==str2.charAt(index2)){
count++;
return longestCommonSequence(str1,index1-1,str2,index2-1,count);
}else{
return Math.max(longestCommonSequence(str1,index1-1,str2,index2,count),
longestCommonSequence(str1,index1,str2,index2-1,count));
}
}
方法二 动态规划(自底向上)
public int longestCommonSubsequence(String str1, String str2) {
if(str1.isEmpty()||str2.isEmpty()) return 0;
int m=str1.length(), n=str2.length();
int[][] dp = new int[m+1][n+1];
for(int i=1; i<=m; i++){
for(int j=1; j<=m; j++){
if(str1.charAt(i-1)==str2.charAt(j-1)){
dp[i][j]=dp[i-1][j-1]+1;
}else{
dp[i][j]=Math.max(dp[i-1][j],dp[i][j-1]);
}
}
}
return dp[m][n];
}