题目:给两个字符串,要求返回这俩字符串的最长公共子序列。
比如:两个字符串如下
“123aase234”
“s23se43”
返回:5
/**
* 求解模型: 序列匹配
* leetcode 1143 题, 求两个字符串的最长公共子序列的长度
*/
public class Code01_LongestCommonSubsequence {
/*==============暴力递归版本=================*/
public static int longestCommonSubsequence(String text1, String text2) {
if(text1 == null || text2 == null || text1.length() == 0 || text2.length() == 0){
return 0;
}
char[] str1 = text1.toCharArray();
char[] str2 = text2.toCharArray();
return process01(str1, str2, text1.length()-1, text2.length()-1);
}
private static int process01(char[] text1, char[] text2, int i, int j) {
if(i == 0 && j == 0){
return text1[i] == text2[j] ? 1 : 0;
}
if(i == 0){ // text1 到最后了
if(text1[i] == text2[j]){
return 1;
}else{
return process01(text1,text2,i,j-1);
}
}else if(j == 0){ // text2 到最后了
if(text1[i] == text2[j]){
return 1;
}else{
return process01(text1,text2,i-1,j);
}
}else{ // text1 与 text2 都没有到最后
// 情况一: 认为公共子序列一定不包含text1 的 i 位置的字符,可以包含 text2 的 j 位置的字符
int p1 = process01(text1,text2,i-1,j);
// 情况二: 认为公共子序列一定不包含text2 的 j 位置的字符,可以包含 text1 的 i 位置的字符
int p2 = process01(text1,text2,i,j-1);
// 情况三: 认为公共子序列包含text1与text2的i,j位置的字符,判断二者是否相等?
// 若等:最长公共子序列 + 1 , 计算 i-1 和 j-1 位置的最长公共子序列
// 若不等:返回0,
int p3 = text1[i] == text2[j] ? 1 + process01(text1,text2,i-1,j-1) : 0;
return Math.max(p1,Math.max(p2,p3));
}
}
/*==============动态规划版本=================*/
/**
* dp版本 , 可通过暴力递归改进而来
* @param text1
* @param text2
* @return
*/
public static int longestCommonSubsequence02(String text1, String text2) {
if(text1 == null || text2 == null || text1.length() == 0 || text2.length() == 0){
return 0;
}
char[] str1 = text1.toCharArray();
char[] str2 = text2.toCharArray();
int N = str1.length;
int M = str2.length;
int[][] dp = new int[N][M];
dp[0][0] = str1[0] == str2[0] ? 1 : 0;
for (int j = 1; j < M; j++) {
dp[0][j] = str1[0] == str2[j] ? 1 : dp[0][j-1];
}
for (int i = 1; i < N; i++) {
dp[i][0] = str1[i] == str2[0] ? 1 : dp[i-1][0];
}
for (int i = 1; i < N; i++) {
for (int j = 1; j < M; j++) {
int p1 = dp[i-1][j];
int p2 = dp[i][j-1];
int p3 = (str1[i] == str2[j]) ? (1 + dp[i-1][j-1]) : 0;
dp[i][j] = Math.max(p1,Math.max(p2,p3));
}
}
return dp[N-1][M-1];
}
}