最長共同字串

最長共同子串(Longest Common Substring)問題是在兩串或多串字串中找出最長的共同子串。例如,對於字串 "ABCDAB" 和 "ABCDBA",它們的最長共同子串是 "ABCD"。

這個問題可以用動態規劃(Dynamic Programming)來解決。我們可以定義一個二維數組 lcs[i][j],其中 i 和 j 分別表示字串 A 和 B 的下標,lcs[i][j] 表示字串 A 的第 i 個字元到字串 B 的第 j 個字元的最長共同子串長度。

可以使用以下遞推公式來計算 lcs[i][j]:

lcs[i][j] = 最大(lcs[i-1][j-1] + 1 if A[i] == B[j] else 0, lcs[i][j-1], lcs[i-1][j])

這裡的 +1 表示如果 A[i] == B[j],則當前字元也匹配,所以最長共同子串的長度增加 1。如果 A[i] != B[j],則當前字元不匹配,我們取 lcs[i-1][j-1]、lcs[i][j-1] 和 lcs[i-1][j] 三者中的最大值,這三個值分別表示:

最後,最長共同子串的長度就是 lcs[n][m],其中 n 和 m 分別是字串 A 和 B 的長度。

以下是一個簡單的 Python 實現:

def lcs(str1, str2):
    n, m = len(str1), len(str2)
    lcs_length = [[0 for _ in range(m + 1)] for _ in range(n + 1)]

    for i in range(n):
        for j in range(m):
            if str1[i] == str2[j]:
                lcs_length[i + 1][j + 1] = lcs_length[i][j] + 1
            else:
                lcs_length[i + 1][j + 1] = max(lcs_length[i + 1][j], lcs_length[i][j + 1], lcs_length[i][j])

    return lcs_length[n][m]

str1 = "ABCDAB"
str2 = "ABCDBA"
print(lcs(str1, str2))

這個算法的時間複雜度為 O(mn),其中 m 和 n 分別是兩串字串的長度。空間複雜度為 O(mn),因為我們使用了二維數組 lcs_length。如果字串較長,可以使用一些優化技巧,比如使用二維哈希表來加速比較過程。