最长子序列和最长子串是不同的,前者不要求字符连续。
参考自:https://blog.csdn.net/qq_31881469/article/details/77892324
1.先是最长子序列的解法:
1 public static int commonSubString(String s1, String s2) { 2 //因为递推公式需要用到i-1,j-1所以把所有矩阵中的内容向下和向右移动,有助于统一处理 3 int length1 = s1.length(); 4 int length2 = s2.length(); 5 int[][] dp = new int[length1+1][length2+1]; 6 for(int i=0; i<=length1; i++) { 7 for(int j=0; j<=length2; j++) { 8 //因为移动了,所以首行首列初始化为0 9 if(i==0||j==0) { 10 dp[i][j] = 0; 11 }else if(s1.charAt(i-1)==s2.charAt(j-1)) { 12 dp[i][j] = dp[i-1][j-1] + 1; 13 14 }else { 15 dp[i][j] = Math.max(dp[i][j-1], dp[i-1][j]); 16 } 17 18 } 19 } 20 return dp[length1][length2]; 21 }
2.接下来是子串
1 public static int commonSubString(String s1, String s2) { 2 //因为递推公式需要用到i-1,j-1所以把所有矩阵中的内容向下和向右移动,有助于统一处理 3 int length1 = s1.length(); 4 int length2 = s2.length(); 5 int[][] dp = new int[length1+1][length2+1]; 6 int result = 0; 7 for(int i=0; i<=length1; i++) { 8 for(int j=0; j<=length2; j++) { 9 //因为移动了,所以首行首列初始化为0 10 if(i==0||j==0) { 11 dp[i][j] = 0; 12 }else if(s1.charAt(i-1)==s2.charAt(j-1)) { 13 dp[i][j] = dp[i-1][j-1] + 1; 14 result = Math.max(dp[i][j], result); 15 }else { 16 dp[i][j] = 0; 17 } 18 } 19 } 20 return result; 21 }
总结:
1.两者的求法比较相似,不同点在于当Xi≠Yj时,X0...Xi与Y0...Yj的最长子序列(LCS)是从(X0...Xi-1,Y0...Yj)的LCS以及 (X0...Xi, Y0...Yj-1)的LCS的较大者。而对于求最长子串来说,此时需要从当前指针指向的字符重新统计。
2.另一个区别在于,LCS可以直接从dp数组中读取,因为数组中最大值一定是dp[maxRow][maxCol]. 而对于子串的情况,需要用一个变量记录下最大值。