1. 程式人生 > 其它 >LeetCode 最長公共子序列LSC

LeetCode 最長公共子序列LSC

技術標籤:letcodeleetcode資料結構

每天一到LeetCode:Day2

題目

給定兩個字串 text1 和 text2,返回這兩個字串的最長公共子序列 lsc 的長度。

一個字串的 子序列 是指這樣一個新的字串:它是由原字串在不改變字元的相對順序的情況下刪除某些字元(也可以不刪除任何字元)後組成的新字串。
例如,“ace” 是 “abcde” 的子序列,但 “aec” 不是 “abcde” 的子序列。兩個字串的「公共子序列」是這兩個字串所共同擁有的子序列。

若這兩個字串沒有公共子序列,則返回 0。

  • 分析
    這是一道典型的二維動態動態規劃問題。
  • 思路分析
    S1:明確dpTable的物理意義
    建立一個二維的dp陣列
    對於上述的例子,可建立如下dpTable:
    在這裡插入圖片描述
    其中,dpTable[i][j]的含義是:對於str1[0,i-1]和str2[0,j-1],他們的LSC長度是dpTable[i][j]。
    S2:定義base case
    讓索引是0 的所有行列都是0。
    如dpTable[0][3] 則表示""與"bab"的LSC是0。

S3:開始遞迴尋找。
如果str1[i]=str[j],那麼則說明該字元一定是在lsc中。
也就是說,此種情況下,如果知道了str1[0…i-1] 和str2[0…j-1]的LSC,那麼加1 就是str1[0…i] 和str2[0…j]的LSC。

if(str1[i]==str2[j]){
   dpTable[i][j]=dpTable[i-1,j-1]+1;
}

如果str1[i]!=str2[j],那麼至少有一個字元不知LSC中,到時是哪一個?我們只取最大就可。

if(str1[i]!=str2[j]){
   dpTable[i][j]=Max(dpTable[i-1][j],dpTable[i][j-1]);
}
  • 完整實現
   public int longestCommonSubsequence(String str1, String str2) {
       int size1=str1.length();
       int
size2=str2.length(); int[][] dptable=new int[size1+1][size2+1]; for(int i=1;i<=size1;i++){ for(int j=1;j<=size2;j++){ if(str1.charAt(i-1)==str2.charAt(j-1)){ dptable[i][j]=dptable[i-1][j-1]+1; }else{ dptable[i][j]=Integer.max(dptable[i-1][j],dptable[i][j-1]); } } } return dptable[size1][size2]; }
  • 結果
    在這裡插入圖片描述