最長共同子序列
最長共同子序列(Longest Common Subsequence, LCS)是一個在電腦科學中常見的問題,它的目標是在兩個或更多的序列中找到最長的公共子序列。子序列是一個序列,它通過從原始序列中移除一些元素得到,而不改變其元素的相對順序。例如,序列 "ABCD" 的子序列包括 "ABCD"、"ABD"、"ACD"、"BCD"、"ABC"、"AB"、"AC"、"AD"、"BC"、"BD"、"CD"、"A"、"B"、"C" 和 "D"。
最長共同子序列問題通常用於比較兩個字元串,但也可以應用於數字序列或其他類型的數據。在字元串的情況下,如果一個字元串是另一個字元串的子序列,那麼它們共享一個子序列。例如,字元串 "ABCDEF" 和 "BDF" 的最長共同子序列是 "BDF"。
解決最長共同子序列問題的一種常見方法是使用動態規劃算法。動態規劃算法通過存儲之前計算的結果來避免重複計算,從而高效地找到最長共同子序列。
以下是動態規劃算法的一個簡單實現:
def lcs(s1, s2):
n, m = len(s1), len(s2)
lcs_length = [0] * (n + 1)
for i in range(n):
for j in range(m):
if s1[i] == s2[j]:
lcs_length[i + 1] = lcs_length[i] + 1
if i > 0 and j > 0 and s1[i - 1] == s2[j - 1]:
lcs_length[i] = max(lcs_length[i], lcs_length[i - 1] + 1)
else:
lcs_length[i] = max(lcs_length[i], lcs_length[i - 1])
lcs_length[i] = max(lcs_length[i], lcs_length[i + 1])
return lcs_length[n]
# 示例
s1 = "ABCDGH"
s2 = "AEDFHR"
print(lcs(s1, s2)) # 輸出: 3
在這個實現中,lcs_length
數組存儲了從 s1
的開頭到 s2
的每個位置的最長公共子序列的長度。lcs_length[n]
就是整個序列的最長公共子序列的長度。
動態規劃算法的時間複雜度通常是 O(mn),其中 m 和 n 分別是兩個序列的長度。對於某些特定情況,可能有更高效的算法,但動態規劃算法是一個通用的解決方案,適用於任何序列。