📅  最后修改于: 2023-12-03 15:40:17.364000             🧑  作者: Mango
最长的公共序列(Longest Common Subsequence,LCS)是在两个字符串中找到一个最长的公共子序列的问题。公共子序列是指在两个序列中,以相同顺序出现的元素组成的子序列。
例如,字符串 "ABCDGH" 和 "AEDFHR" 的最长公共子序列是 "ADH",长度为 3。
LCS 问题涉及到两个字符串。因此,它是一个二维数组上的动态规划问题。算法通常将二维数组表示为一个表格,每个单元格存储 LCS 的长度。
我们可以通过以下步骤来解决 LCS 问题:
1. 初始化: 创建一个二维数组 table[m+1][n+1],其中 m 和 n 是两个字符串的长度(下标从 0 开始),table[i][j] 表示第一个字符串前 i 个字符和第二个字符串前 j 个字符的 LCS 的长度。 对于 i=0 或 j=0,table[i][j] 的值为 0。
2. 填充表格: 遍历字符串中的字符,如果两个字符相等,table[i][j] 的值等于 table[i-1][j-1] 加上 1。否则,table[i][j] 的值等于 Max(table[i-1][j], table[i][j-1])。
3. 最长公共子序列: 从 table[m][n] 开始,向左上角遍历 table 数组,如果当前元素等于 table[i-1][j-1] + 1,则将对应的字符添加到结果字符串中,并向左上角移动。
以下是使用 Python 实现 LCS 算法的代码片段:
def lcs(str1, str2):
m, n = len(str1), len(str2)
table = [[0] * (n+1) for _ in range(m+1)]
for i in range(1, m+1):
for j in range(1, n+1):
if str1[i-1] == str2[j-1]:
table[i][j] = table[i-1][j-1] + 1
else:
table[i][j] = max(table[i-1][j], table[i][j-1])
# 回溯并构造 LCS
i, j = m, n
result = ''
while i > 0 and j > 0:
if str1[i-1] == str2[j-1]:
result = str1[i-1] + result
i, j = i-1, j-1
elif table[i-1][j] > table[i][j-1]:
i -= 1
else:
j -= 1
return result
以上函数接受两个字符串 str1 和 str2,计算它们的最长公共子序列并返回结果。在实现中,我们在 table[m+1][n+1] 中存储 LCS 的长度,并通过回溯构造最长公共子序列。