《计算机算法设计与分析》
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time : 2023/1/20 14:01
# @Author : Lili
# @File : 最长公共子序列.py
# @Description : 算法的空间复杂性可以优化
import array
def lcs_length(p: list, q: list):
"""
最长公共子序列
:param p: 序列X
:param q: 序列Y
:return: 最长序列长度m, 最长公共子序列li
"""
n1 = len(p) + 1
n2 = len(q) + 1
m = [] # 子问题最优解
s = [[0 for j in range(0, n2)]
for i in range(0, n1)] # 记录m[i][j]解相应子问题的解的来源
for i in range(0, n1):
m.append(array.array('i', [0 for j in range(0, n2)]))
for i in range(1, n1):
for j in range(1, n2):
if p[i - 1] == q[j - 1]:
m[i][j] = m[i - 1][j - 1] + 1
s[i][j] = 1
elif m[i - 1][j] >= m[i][j - 1]:
m[i][j] = m[i - 1][j]
s[i][j] = 2
else:
m[i][j] = m[i][j - 1]
s[i][j] = 3
li = []
# 递归回溯
def lcs(i: int, j: int):
if i == 0 or j == 0:
return
elif s[i][j] == 1:
lcs(i - 1, j - 1)
li.append(p[i-1])
elif s[i][j] == 2:
lcs(i - 1, j)
elif s[i][j] == 3:
lcs(i, j - 1)
lcs(n1-1, n2-1)
return m[-1][-1], li
p = list("ABCBDAB")
q = list("BDCABA")
m, s = lcs_length(p, q)
print(m)
print(s)