最长公共子序列

《计算机算法设计与分析》

#!/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)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值