算法导论,动态规划 —— 最长公共子序列问题(LCS)优化python示例

# coding=utf-8
# 计算LCS长度算法    算法 改进    只用 一行 和 一个 额外空间 求得长度   空间复杂度由O(m*n)降低为O(n)
# 空间优化。观察状态转移方程,计算的F[i,j]时只和F[i-1,j-1],F[i,j-1],F[i-1,j]三个元素直接相关。
# 仔细分析一下,在递推F[i]这一行的子问题时,只需要知道F[i-1]一行的值和当前计算的F[i,j]的前一个元素的值f[i,j-1]即可,于是空间复杂度由O(m*n)降低为O(n)。
#                               核心思想
# 初始化一个长m+1全0的序列base[],一个为0的递推前导front和一个当前计算元素pre(意义上的F[i,j]),
# 每次计算完F[i,j]后,front的值更新到base[j-1]上,然后把pre更新到front上,然后向后扫描……注意一行最后一个元素的更新!
# 这样迭代n次,最后base[m]的值即LCS的值!


def lcsLength(x, y):
    m = len(x) + 1
    n = len(y) + 1
    length = min(m, n)
    # 存放箭头方向
    base = [0 for i in range(length)]
    # 已经全部初始化为 0 了   上↑  左←  左上↖
    for i in range(1, m):
        # 进入下一行时 front = 0
        front = 0
        for j in range(1, n):
            # 数组第一个 元素 下标为 0     front值上移成为下一行的上方值   pre值前移成为下一个的front值
            if x[i-1] == y[j-1]:
                pre = base[j-1] + 1
                base[j - 1] = front
                front = pre
            elif base[j] >= front:
                pre = base[j]
                base[j - 1] = front
                front = pre
            else:
                pre = front
                base[j - 1] = front
                front = pre
            # 因为base最后一个元素在判断中没被更新,所以一行循环结束时,单独把base末尾元素更新
            if j == n-1:
                base[j] = front
                print(base)
    return base[length - 1]


x = ['A', 'B', 'C', 'B', 'D', 'A', 'B']
y = ['B', 'D', 'C', 'A', 'B', 'A']
count = lcsLength(x, y)
print("其最长公共子序列长度为:", count)

转载于:https://my.oschina.net/xiaohuoer1995/blog/1600191

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值