如何求最長公共子串的長度
最長公共子串(Longest Common Substring)問題是指在兩個或更多字元串中找到最長的共同子串。這裡有一個簡單的算法來解決這個問題:
-
使用兩個字元串作為例子:
ABCDAB
和ABCDBA
。 -
首先,我們建立一個長度與第一個字元串相同(
ABCDAB
)的二維陣列,用來記錄每個位置上的字元是否已經出現在子串中。 -
從第一個字元串的開頭開始,我們檢查每個字元是否與第二個字元串的對應位置上的字元匹配。如果匹配,我們將子串的長度加1,並將指針向後移動一位。如果不匹配,我們將子串的長度存入一個變量中,並將指針向後移動一位。
-
我們重複這個過程,直到我們達到第一個字元串的末尾。
-
最後,我們返回存入變量中的最長子串長度。
以下是一個簡單的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)
,其中m
和n
分別是兩個字元串的長度。空間複雜度是O(mn)
,因為我們使用了大小為mn
的二維陣列。
對於多個字元串的情況,我們可以將上面的算法應用於每一對字元串對,然後找到最長子串長度中的最大值。這樣做的時間複雜度是O(n^3)
,因為我們需要比較每對字元串。如果我們想要更高效的算法,可以使用分而治之的方法,如Karp-Rabin算法或Knuth-Morris-Pratt算法,但這些算法通常用於查找最長公共子序列(Longest Common Subsequence),而不是最長公共子串。