一、最長公共子序列和最長公共子串的區別?算法
最長公共子序列:不要求子序列連續。數組
最長公共子串:要求子串必定連續。spa
二、最長公共子序列3d
最長公共子序列定義:兩個或多個已知數列的子序列集合中最長的就是最長公共子序列。code
好比數列A = 「abcdef」和B = 「adefcb」,那麼兩個數列的公共子序列集合有{」a","ab","abc","adef",等等},其中最長的就是adef,這就是最長公共子序列。blog
dp[i][j] -- 表示子串A[0...i](數組長度爲n)和子串B[0...j](數組長度爲m)的最長公共子序列遞歸
當A[i] == B[j]時,dp[i][j] = dp[i-1][j-1] + 1;string
不然,dp[i][j] = max(dp[i-1][j], dp[i][j-1]);io
最優解爲dp[n-1][m-1];
class
回溯輸出最長公共子序列過程:
算法分析:
因爲每次調用至少向上或向左(或向上向左同時)移動一步,故最多調用(m * n)次就會遇到i = 0或j = 0的狀況,此時開始返回。返回時與遞歸調用時方向相反,步數相同,故算法時間複雜度爲Θ(m * n)。
1 public class Solution { 2 3 public static void main(String[] args) { 4 String str1 = "12asdfa"; 5 String str2 = "we2rasdaswer"; 6 7 int result = longestCommonSubsequence(str1, str2); 8 System.out.println(result); 9 10 } 11 12 // LCS 13 public static int longestCommonSubsequence(String str1, String str2) { 14 int[][] matrix = new int[str1.length()+1][str2.length()+1]; 15 16 for(int i = 0; i < str1.length(); i++) { 17 matrix[i][0] = 0; 18 } 19 20 for(int j = 0; j <= str2.length(); j++) { 21 matrix[0][j] = 0; 22 } 23 24 for(int i = 1; i <= str1.length(); i++) { 25 for(int j = 1; j <= str2.length(); j++) { 26 if(str1.charAt(i-1) == str2.charAt(j-1)) { 27 matrix[i][j] = matrix[i-1][j-1] + 1; 28 } else { 29 matrix[i][j] = (matrix[i-1][j] >= matrix[i][j-1]?matrix[i-1][j]:matrix[i][j-1]); 30 } 31 } 32 } 33 34 return matrix[str1.length()][str2.length()]; 35 } 36 }
如何要獲得重複的子序列是哪一個?
三、最長公共子串
最長公共子串的動態規劃的狀態轉移方程式
1 public class Solution { 2 public static void main(String[] args) { 3 4 String str1 = "abcdef"; 5 String str2 = "cde"; 6 7 int result = longestCommonSubstring(str1, str2); 8 System.out.println(result); 9 } 10 11 public static int longestCommonSubstring(String str1, String str2) { 12 int len1 = str1.length(); 13 int len2 = str2.length(); 14 int result = 0; 15 16 int[]][] c = new int[len1+1][len2+1]; 17 18 for(int i = 0; i <= len1; i++) { 19 for(int j = 0; j <= len2; j++) { 20 21 if(i == 0 || j == 0) { 22 c[i][j] = 0; 23 } else if(str1.charAt(i-1) == str2.charAt(j)) { 24 c[i][j] = c[i-1][j-1] + 1; 25 result = Math.max(result, c[i][j]); 26 } else { 27 c[i][j] = 0; 28 } 29 } 30 } 31 32 return result; 33 } 34 }