如何恢復最長公共子序列
最長公共子序列(Longest Common Subsequence, LCS)問題是在兩個或更多序列中找到最長的公共子序列。這裡有一個簡單的算法來恢復兩個序列的LCS:
- 使用動態規劃算法來找到兩個序列的LCS的長度。
- 使用回溯法來找到實際的LCS。
下面是一個簡單的Python實現:
def lcs(seq1, seq2):
m, n = len(seq1), len(seq2)
lcs_length = 0
# Create a table to store the lengths of LCS of prefixes of X and Y
lcs_lengths = [[0 for col in range(n)] for row in range(m)]
# Fill the lcs_lengths table in bottom-up manner
for i in range(m):
for j in range(n):
if seq1[i] == seq2[j]:
lcs_lengths[i][j] = lcs_length + 1
if i > 0 and j > 0:
lcs_lengths[i][j] = max(lcs_lengths[i][j], lcs_lengths[i-1][j-1])
lcs_length = lcs_lengths[i][j]
else:
lcs_lengths[i][j] = 0
# The value in lcs_lengths[m-1][n-1] is the length of LCS
return lcs_lengths[m-1][n-1]
def restore_lcs(seq1, seq2, lcs_length):
lcs = []
i, j = len(seq1) - 1, len(seq2) - 1
while i >= 0 and j >= 0:
if seq1[i] == seq2[j]:
lcs.insert(0, seq1[i])
i -= 1
j -= 1
elif lcs_lengths[i][j] == lcs_lengths[i-1][j] or lcs_lengths[i][j] == lcs_lengths[i][j-1]:
i -= 1
else:
j -= 1
return lcs
# Example usage:
seq1 = "ABCDGH"
seq2 = "AEDFHR"
lcs_length = lcs(seq1, seq2)
print("The length of the LCS is:", lcs_length)
lcs = restore_lcs(seq1, seq2, lcs_length)
print("The LCS is:", lcs)
這個算法的時間複雜度是O(mn),其中m和n是兩個序列的長度。空間複雜度也是O(mn),因為我們需要一個大小為m*n的表來存儲動態規劃的狀態。