尝试寻找重复子问题,一般针对两个字符串问题,都是通过转换成二维,来得出状态数组和递推公式
上面text1="ABAZDC", text2="BACBAD"
设dp[i][j] 为字符串text1的子串(0,j]与字符串text2子串(0,i]的最长公共子序列长度
从上图可以得出递推公式如下:
当text1[j] == text2[i] :dp[i][j] = dp[i-1][j-1] + 1;
当text1[j] != text2[i] :dp[i][j] = Math.max(dp[i-1][j], dp[i][j-1]);
先初始化第一行和第一列的值,然后通过递推公式即可算出所有dp的值
public class Test1143 {
@Test
public void test() {
String text1 = "pmjghexybyrgzczy";
String text2 = "hafcdqbgncrcbihkd";
System.out.println(longestCommonSubsequence(text1, text2));
}
/**
* t e x t 1
* t
* e
* x
* t
* 2
* @param text1
* @param text2
* @return
*/
public int longestCommonSubsequence(String text1, String text2) {
char[] text1Array = text1.toCharArray();
char[] text2Array = text2.toCharArray();
int[][] dp = new int[text2.length()][text1.length()];
// 初始化第一行
boolean flag1 = false;
for (int j = 0; j < text1Array.length; j++) {
if (text1Array[j] == text2Array[0] || flag1) {
dp[0][j] = 1;
flag1 = true;
} else {
dp[0][j] = 0;
}
}
// 初始化第一列
boolean flag2 = false;
for (int i = 0; i < text2Array.length; i++) {
if (text2Array[i] == text1Array[0] || flag2) {
dp[i][0] = 1;
flag2 = true;
} else {
dp[i][0] = 0;
}
}
for (int i = 1; i < text2Array.length; i++) {
for (int j = 1; j < text1Array.length; j++) {
if (text2Array[i] == text1Array[j]) {
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[text2Array.length - 1][text1Array.length - 1];
}
}