最长公共子序列问题用动态规划解,要输出最长公共子序列,并有改进,python代码,要有逐行注释,并要求结果正确
时间: 2024-02-13 17:06:56 浏览: 64
最长公共子序列问题 动态规划
4星 · 用户满意度95%
好的,下面是最长公共子序列问题的动态规划解法,并输出最长公共子序列。
```python
def lcs(X, Y):
# 获取两个字符串的长度
m = len(X)
n = len(Y)
# 创建一个二维数组来存储子问题的解
# dp[i][j] 表示 X[:i] 和 Y[:j] 的最长公共子序列的长度
dp = [[0] * (n + 1) for _ in range(m + 1)]
# 从左到右和从上到下遍历数组
for i in range(1, m + 1):
for j in range(1, n + 1):
# 如果当前字符相同,则最长公共子序列长度加一
if X[i-1] == Y[j-1]:
dp[i][j] = dp[i-1][j-1] + 1
else:
# 否则选取上一个状态中较长的一个
dp[i][j] = max(dp[i-1][j], dp[i][j-1])
# 从 dp[m][n] 开始,通过 dp 数组反向构建最长公共子序列
index = dp[m][n]
lcs = [""] * (index+1)
lcs[index] = ""
i = m
j = n
while i > 0 and j > 0:
# 如果当前字符相同,则加入最长公共子序列中
if X[i-1] == Y[j-1]:
lcs[index-1] = X[i-1]
i -= 1
j -= 1
index -= 1
# 否则,移动较大的一个指针
elif dp[i-1][j] > dp[i][j-1]:
i -= 1
else:
j -= 1
# 返回最长公共子序列
return "".join(lcs[1:])
# 测试
X = "ABCBDAB"
Y = "BDCABA"
print("最长公共子序列为:", lcs(X, Y))
```
这是一个经典的动态规划问题,时间复杂度为 $O(mn)$,其中 $m$ 和 $n$ 分别为两个字符串的长度。对于最长公共子序列的求解,我们需要在 dp 数组中记录路径,然后通过反向遍历 dp 数组,构建最长公共子序列。
阅读全文