最長共同子序列

最長共同子序列(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 分別是兩個序列的長度。對於某些特定情況,可能有更高效的算法,但動態規劃算法是一個通用的解決方案,適用於任何序列。