题目:给定两个字符串A和B,返回两个字符串的最长公共子序列的长度。例如,A="1A2C3D4B56”,B="B1D23CA45B6A”,”123456"或者"12C4B6"都是最长公共子序列。给定两个字符串A和B,同时给定两个串的长度n和m,请返回最长公共子序列的长度。保证两串长度均小于等于300。
思路:维护一个二维dp数组,dp[i][j]代表A[0...i]和B[0....j]里有多少个相同字符,对于dp[i][0]即第一列,相当于只拿出B[0]和A[i]比较,那么如果A中某个字符和B[0]一样,dp[i][0]=1,那么i之后的dp[i+1,i+2...][0]也为1,同理可求dp[0][i],由特殊到一般,,求dp[i][j],它的值可能来自三种情况,要是刚好i=j并且A[i]=B[j]
就是相当于数组同时增加一个字符,而这两个字符恰好一样,那么此时dp[i][j]=dp[i-1][j-1]+1;除此之外,要么是dp[i-1][j],要么是dp[i][j-1],这两个哪个大就是哪个。
public int findLCS(String A, int n, String B, int m) { int[][] dp = new int[n][m];
//初始化第一列 for(int i=0;i<n;i++){ if(A.charAt(i)==B.charAt(0)){ dp[i][0]=1; for(int j=i+1;j<n;j++){ dp[j][0]=1; } break; } }
//初始化第一行 for(int i=0;i<m;i++){ if(B.charAt(i)==A.charAt(0)){ dp[0][i]=1; for(int j=i+1;j<m;j++){ dp[0][j]=1; } break; } }
//由上到下,由左到右赋值 for(int i=1;i<n;i++){ for(int j=1;j<m;j++){ if(A.charAt(i)==B.charAt(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[n-1][m-1]; }