求解最長公共子序列問題(LCS)

刷leetcode一直沒做到大名鼎鼎的LCS問題,也不明白LCS具體是什麼問題,直到做到去年騰訊筆試的一道編程題:


給定一個字符串s,你可以從中刪除一些字符,使得剩下的串是一個迴文串。如何刪除才能使得迴文串最長呢?
輸出需要刪除的字符個數。

輸入描述:

輸入數據有多組,每組包含一個字符串s,且保證:1<=s.length<=1000.



輸出描述:

對於每組數據,輸出一個整數,代表最少需要刪除的字符個數。


輸入例子:
abcda
google

輸出例子:
2

2



最初毫無頭緒,還想着能不能通過思考解最長迴文串的解法來解答,後來實在無果,借鑑網上的解答,發現可以使用字符串反轉然後求LCS問題來輕鬆解答。於是寫下這篇博文,也算是爲自己了了LCS問題這個坑。

"

什麼是最長公共子序列呢?舉個簡單的例子吧,一個數列S,若分別是兩個或多個已知序列的子序列,且是所有符合條件序列中最長的,則S稱爲已知序列的最長公共子序列。

  舉例如下,如:有兩個隨機數列,1 2 3 4 5 6 和 3 4 5 8 9,則它們的最長公共子序列便是:3 4 5。

  一直不明白:最長公共子串和最長公共子序列的區別。
  
   上網查了下,最長公共子串(Longest Common Substirng)和最長公共子序列(Longest Common Subsequence,LCS)的區別爲:子串是串的一個連續的部分,子序列則是從不改變序列的順序,而從序列中去掉任意的元素而獲得新的序列;也就是說,子串中字符的位置必須是連續的,子序列則可以不必連續。
"


這是我最初不能理解LCS的主要原因,我還把他當作字符串問題來解決。

這道題可以通過動態規劃來做。


首先初始化一個二維數組lcs[][],各元素均爲0;

現在對這個數組進行狀態及遞推的判斷,i,j分別從0開始,雙層循環。

如果str1[i]==str[j]則lcs[i][j]=lcs[i-1][j-1]+1;

如果str1[i]!=str[j],那麼lcs[i][j]=max(lcs[i][j-1],lcs[i-1][j])   /*這句話必須理解,這是算法的關鍵,可以結果棋盤圖去思考


有了這個遞推關係,解答就很簡單了·~~~~

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章