📅  最后修改于: 2023-12-03 15:25:46.217000             🧑  作者: Mango
最长公共子序列(Longest Common Subsequence,LCS)是一道经典的算法问题,用来求解两个序列的最长子序列的长度。最长子序列不要求连续,但是需要保证顺序一致。例如字符串 "abcde" 和 "ace" 的最长公共子序列是 "ace"。
这里我们将介绍如何打印最长公共子序列的具体方法,并提供代码示例。
暴力枚举法是最朴素的求解方法,它采用两重循环依次枚举两个序列所有的共同子序列,然后返回最长的那个子序列即可。
时间复杂度为 $O(2^n)$,效率较低,不建议实际应用。
def longestCommonSubsequence(s1, s2):
"""
暴力枚举法
"""
def dfs(i, j):
if i == len(s1) or j == len(s2):
return []
if s1[i] == s2[j]:
return [s1[i]] + dfs(i+1, j+1)
else:
return max(dfs(i+1, j), dfs(i, j+1), key=len)
return dfs(0, 0)
s1 = "abcde"
s2 = "ace"
print(longestCommonSubsequence(s1, s2)) # 输出: ['a', 'c', 'e']
动态规划是求解最长公共子序列问题的经典方法,它将问题划分为若干个子问题,并将子问题之间的关系表示为状态转移方程式,从而得到最长公共子序列的长度。
时间复杂度为 $O(mn)$,其中 m 和 n 分别是两个序列的长度。
def printLCS(s1, s2):
"""
动态规划法
"""
m, n = len(s1), len(s2)
dp = [["" for _ in range(n+1)] for _ in range(m+1)]
for i in range(1, m+1):
for j in range(1, n+1):
if s1[i-1] == s2[j-1]:
dp[i][j] = dp[i-1][j-1] + s1[i-1]
else:
dp[i][j] = max(dp[i-1][j], dp[i][j-1], key=len)
return dp[m][n]
s1 = "abcde"
s2 = "ace"
print(printLCS(s1, s2)) # 输出: ace
以上即为打印最长公共子序列的两种实现方式,使用动态规划的方法更为高效,可以在实际应用中使用。