最長公共子序列
- 題目描述:給定兩個字符串s1 s2 … sn和t1 t2 … tm 。求出這兩個字符串的最長公共子序列的長度。字符串s1 s2 … sn的子序列指可以表示為
…
{ i1 < i2 < … < ik }的序列。
- 輸入樣例
2
asdf
adfsd
123abc
abc123abc
- 輸出樣例
3
6
- 解題思路:
這道題是被稱為最長公共子序列的問題(LCS,Longest Common Subsequence)的著名問題。這道題我們是用動態規划的思想來做的。我們先拿第一組測試用例,asdf 與 adfsd 作為例子來看一下這道題的思路。上圖!!
j / i | 0 | 1(a) | 2(s) | 3(d) | 4(f) |
0 | 0 | 0 | 0 | 0 | 0 |
1(a) | 0 | 1 | 1 | 1 | 1 |
2(d) | 0 | 1 | 1 | 2 | 2 |
3(f) | 0 | 1 | 1 | 2 | 3 |
4(s) | 0 | 1 | 2 | 2 | 3 |
5(d) | 0 | 1 | 2 | 2 | 3 |
做這種題,我們要用一個二維數組(dp[MAX_N][MAX_N])來存放每一個狀態的值。如圖所示,橫向代表i、縱向代表j,那么,每一個網格的值是怎么來的呢。在這里我們把每一個狀態即dp[i][j] 看做 s1 … si 和 t1 … tj 的LCS的長度。由此我們,s1 … s(i+1) 和 t1 … t(j+1) 對應的公共子列長度可能是:
當s(i+1) == t(j+1),在 s1 … si 和 t1 … tj 的公共子列末尾追加上s(i+1) 。
否則則可能是 s1 … si 和 t1 … t(j+1) 的公共子列或者 s1 … s(i+1) 和 t1 … tj 的公共子列最大值。
對應以下一個公式:
有了上面的公式我們就可以寫代碼了: