[编程题] 最长公共子序列
对于两个字符串,请设计一个高效算法,求他们的最长公共子序列的长度,这里的最长公共子序列定义为有两个序列U1,U2,U3...Un和V1,V2,V3...Vn,其中Ui<Ui+1,Vi<Vi+1。且A[Ui] == B[Vi]。
给定两个字符串A和B,同时给定两个串的长度n和m,请返回最长公共子序列的长度。保证两串长度均小于等于300。
测试样例:
"1A2C3D4B56",10,"B1D23CA45B6A",12
返回:6
解法思路:
建立一个dp矩阵,是两个字符串一个纵对应,一个横向对应。
dp[i][j]表示str1[0...i]和str2[0...j]的最长公共子序列的长度
求解 dp[i][j]为:
若str1[i] == str2[j],则 dp[i][j] = max( dp[i-1][j], dp[i][j-1], dp[i-1][j-1]+1 )
若str1[i] != str2[j],则 dp[i][j] = max( dp[i-1][j], dp[i][j-1] )
最后返回dp[M-1][N-1],M、N为两个字符串的长度
1 public static int findLCS(String A, int n, String B, int m) { 2 int[][] dp = new int[n+1][m+1]; 3 for (int i = 1; i <= n; i++) { 4 for (int j = 1; j <= m; j++) { 5 if(A.charAt(i-1)==B.charAt(j-1)){ 6 dp[i][j] = Math.max(Math.max(dp[i-1][j],dp[i][j-1]), dp[i-1][j-1]+1); 7 }else{ 8 dp[i][j] = Math.max(dp[i-1][j],dp[i][j-1]); 9 } 10 } 11 } 12 return dp[n][m]; 13 }
Jumping from failure to failure with undiminished enthusiasm is the big secret to success.