如何求最長公共子串的長度

最長公共子串(Longest Common Substring)問題是指在兩個或更多字元串中找到最長的共同子串。這裡有一個簡單的算法來解決這個問題:

  1. 使用兩個字元串作為例子:ABCDABABCDBA

  2. 首先,我們建立一個長度與第一個字元串相同(ABCDAB)的二維陣列,用來記錄每個位置上的字元是否已經出現在子串中。

  3. 從第一個字元串的開頭開始,我們檢查每個字元是否與第二個字元串的對應位置上的字元匹配。如果匹配,我們將子串的長度加1,並將指針向後移動一位。如果不匹配,我們將子串的長度存入一個變量中,並將指針向後移動一位。

  4. 我們重複這個過程,直到我們達到第一個字元串的末尾。

  5. 最後,我們返回存入變量中的最長子串長度。

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

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

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

    return dp[n][m]

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

這個算法的時間複雜度是O(mn),其中mn分別是兩個字元串的長度。空間複雜度是O(mn),因為我們使用了大小為mn的二維陣列。

對於多個字元串的情況,我們可以將上面的算法應用於每一對字元串對,然後找到最長子串長度中的最大值。這樣做的時間複雜度是O(n^3),因為我們需要比較每對字元串。如果我們想要更高效的算法,可以使用分而治之的方法,如Karp-Rabin算法或Knuth-Morris-Pratt算法,但這些算法通常用於查找最長公共子序列(Longest Common Subsequence),而不是最長公共子串。