最长公共子序列
1.算法思路
主要流程如上图所示,动态规划主要体现在两个辅助的二维数组(把每一步执行所的的结果都存起来)。最后,构造最优解的时候,利用辅助二维数组得到最优解
*2.算法实现
def LCS(lisx, lisy):
# 构造最优解,x 和 y 从最大值出发,直到有一个为 0(到边上了)
def struct(x, y, s, lisx):
res = []
if x == 0 or y == 0:
return
if s[x][y] == '左上':
struct(x - 1, y - 1, s, lisx)
print(lisx[x - 1])
elif s[x][y] == '上':
struct(x - 1, y, s, lisx)
else:
struct(x, y - 1, s, lisx)
steps = [[''] * (len(lisy) + 1) for _ in range(len(lisx) + 1)] # 用来存储当前位置是由那个位置延伸的
count = [[0] * (len(lisy) + 1) for _ in range(len(lisx) + 1)] # 用来存储当前公共序列的第几个元素(只是起辅助作用)
# 计算出所有公共子序列
for i in range(1, len(lisx) + 1):
for j in range(1, len(lisy) + 1):
if lisx[i - 1] == lisy[j - 1]: # steps和count的长度比两个列表大 1
count[i][j] = count[i-1][j-1] + 1
steps[i][j] = '左上'
elif count[i-1][j] >= count[i][j-1]:
count[i][j] = count[i-1][j]
steps[i][j] = '上'
else:
count[i][j] = count[i][j-1]
steps[i][j] = '左'
# 调用构造函数
struct(len(lisx), len(lisy), steps, lisx)