【动态规划】最长公共子序列Python实现

这篇具有很好参考价值的文章主要介绍了【动态规划】最长公共子序列Python实现。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

个人主页:丷从心

系列专栏:动态规划算法


问题描述

  • 给定两个序列 X = {   x 1 , x 2 , ⋯   , x m   } X = \set{x_{1} , x_{2} , \cdots , x_{m}} X={x1,x2,,xm} Y = {   y 1 , y 2 , ⋯   , y n   } Y = \set{y_{1} , y_{2} , \cdots , y_{n}} Y={y1,y2,,yn},找出 X X X Y Y Y的最长公共子序列

最长公共子序列的结构

  • 设序列 X = {   x 1 , x 2 , ⋯   , x m   } X = \set{x_{1} , x_{2} , \cdots , x_{m}} X={x1,x2,,xm} Y = {   y 1 , y 2 , ⋯   , y n   } Y = \set{y_{1} , y_{2} , \cdots , y_{n}} Y={y1,y2,,yn}的最长公共子序列为 Z = {   z 1 , z 2 , ⋯   , z k   } Z = \set{z_{1} , z_{2} , \cdots , z_{k}} Z={z1,z2,,zk}
    • x m = y n x_{m} = y_{n} xm=yn,则 z k = x m = y n z_{k} = x_{m} = y_{n} zk=xm=yn,且 Z k − 1 Z_{k - 1} Zk1 X m − 1 X_{m - 1} Xm1 Y n − 1 Y_{n - 1} Yn1的最长公共子序列
    • x m ≠ y n x_{m} \neq y_{n} xm=yn z k ≠ x m z_{k} \neq x_{m} zk=xm,则 Z Z Z X m − 1 X_{m - 1} Xm1 Y Y Y的最长公共子序列
    • x m ≠ y n x_{m} \neq y_{n} xm=yn z k ≠ y n z_{k} \neq y_{n} zk=yn,则 Z Z Z X X X Y n − 1 Y_{n - 1} Yn1的最长公共子序列

子问题的递归结构

  • x m = y n x_{m} = y_{n} xm=yn时,找出 X m − 1 X_{m - 1} Xm1 Y n − 1 Y_{n - 1} Yn1的最长公共子序列,然后在其尾部加上 x m x_{m} xm
  • x m ≠ y n x_{m} \neq y_{n} xm=yn时,找出 X m − 1 X_{m - 1} Xm1 Y Y Y的一个最长公共子序列及 X X X Y n − 1 Y_{n - 1} Yn1的一个最长公共子序列,这两个公共子序列中较长者即为 X X X Y Y Y的最长公共子序列
c [ i ] [ j ] c[i][j] c[i][j]递归方程

c [ i ] [ j ] = { 0 , i = 0 或 j = 0 c [ i − 1 ] [ j − 1 ] + 1 , i , j > 0 ; x i = y j max ⁡ {   c [ i ] [ j − 1 ] , c [ i − 1 ] [ j ]   } , i , j > 0 ; x i ≠ y j c[i][j] = \begin{cases} 0 , & i = 0 或 j = 0 \\ c[i - 1][j - 1] + 1 , & i , j > 0 ; x_{i} = y_{j} \\ \max\set{c[i][j - 1] , c[i - 1][j]} , & i , j > 0 ; x_{i} \neq y_{j} \end{cases} c[i][j]= 0,c[i1][j1]+1,max{c[i][j1],c[i1][j]},i=0j=0i,j>0;xi=yji,j>0;xi=yj文章来源地址https://www.toymoban.com/news/detail-829929.html


时间复杂性

  • 由于每个数组单元的计算耗费 O ( 1 ) O(1) O(1)时间,因此算法耗时 O ( m n ) O(mn) O(mn)

构造最长公共子序列

  • 在算法 L C S LCS LCS中,每次递归调用使 i i i j j j 1 1 1,因此算法的计算时间为 O ( m + n ) O(m + n) O(m+n)

Python实现

def longest_common_subsequence(str_1, str_2):
    m = len(str_1)
    n = len(str_2)

    # 创建一个二维数组来存储子问题的解
    dp = [[0] * (n + 1) for _ in range(m + 1)]

    # 填充二维数组
    for i in range(1, m + 1):
        for j in range(1, n + 1):
            if str_1[i - 1] == str_2[j - 1]:
                dp[i][j] = dp[i - 1][j - 1] + 1
            else:
                dp[i][j] = max(dp[i - 1][j], dp[i][j - 1])

    # 构造最长公共子序列
    lcs = ''

    i, j = m, n
    while i > 0 and j > 0:
        if str_1[i - 1] == str_2[j - 1]:
            lcs = str_1[i - 1] + lcs

            i -= 1
            j -= 1
        elif dp[i - 1][j] > dp[i][j - 1]:
            i -= 1
        else:
            j -= 1

    return lcs


str_1 = 'ABCDGH'
str_2 = 'AEDFHR'

lcs = longest_common_subsequence(str_1, str_2)

print(f'最长公共子序列: {lcs}')
最长公共子序列: ADH

算法的改进

  • 如果只需要计算最长公共子序列的长度,则只用到数组 c c c的第 i i i行和第 i − 1 i - 1 i1
  • 因此,用两行的数组空间就可以计算出最长公共子序列的长度,可将空间需求减至 O ( min ⁡ {   m , n   } ) O(\min\set{m , n}) O(min{m,n})

到了这里,关于【动态规划】最长公共子序列Python实现的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 算法:动态规划——最长公共子序列

    动态规划算法与分治法类似,其基本思想也是将待求解问题分解成若干个子问题,先求解子问题,然后从这些子问题的解得到原问题的解。 与分治法不同的是,适合于用动态规划法求解的问题,经分解得到的子问题往往不是互相独立的。若用分治法解这类问题,则分解得到的

    2023年04月27日
    浏览(46)
  • 【算法-动态规划】最长公共子序列

    💝💝💝欢迎来到我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 推荐:kuan 的首页,持续学习,不断总结,共同进步,活到老学到老 导航 檀越剑指大厂系列:全面总

    2024年01月23日
    浏览(38)
  • 【动态规划】最长公共子序列(Java)

    给定两个字符串 text1 和 text2,返回这两个字符串的最长 公共子序列 的长度。如果不存在 公共子序列 ,返回 0 。 一个字符串的 子序列 是指这样一个新的字符串:它是由原字符串在不改变字符的相对顺序的情况下删除某些字符(也可以不删除任何字符)后组成的新字符串。

    2024年01月18日
    浏览(57)
  • 动态规划之最长公共子序列模板

    夏令营:动态规划特训 - 【算法模板题】最长公共子序列 - 蓝桥云课 (lanqiao.cn) 我们来解释一下状态转移方程吧。 dp[i][j]的含义是第i个和第j个字符,i与j的下标从1开始,代表着原子符串的第一个字符。那么理所当然字符串a的第0个字符和字符串b的0个字符的公共长度为0.如果字

    2024年02月12日
    浏览(31)
  • 动态规划-最长公共子序列(c语言)

    实验 3: 最长公共子序列 内容: 给定两个字符串str1和str2,输出两个字符串的最长公共子序列,如果最长公共子序列为空,则返回“-1”。目前给出的数据,仅仅会存在一个最长的公共子序列。 数据范围: 0 ≤|str1|,|str2|≤2000 要求: 空间复杂度O(n 2 ) 具体思路: step1:

    2024年02月04日
    浏览(32)
  • 动态规划-----最长公共子序列(及其衍生问题)

    目录 一.最长公共子序列的基本概念: 解决动态规划问题的一般思路(三大步骤): 二.最长公共子序列题目: 三.字符串的删除操作: 四.最小 ASCII 删除和: 首先需要科普一下,最长公共子序列(longest common sequence)和最长公共子串(longest common substring)不是一回事儿。什么

    2024年03月26日
    浏览(34)
  • 【动态规划】最长公共子序列——算法设计与分析

    子序列是给定序列中在任意位置去掉任意多个字符后得到的结果。例如: 给定序列 X X X : X : A B C B D A B X:ABCBDAB X : A BCB D A B X X X 的子序列: X 1 : A B C B D A B X_1:ABCBDAB X 1 ​ : A BCB D A B X 2 : A B C B X_2:ABCB X 2 ​ : A BCB X 3 : A C B B X_3:ACBB X 3 ​ : A CBB 给定两个序列

    2024年02月05日
    浏览(36)
  • (Java) 算法——动态规划 最长公共子序列 图解

    遇到了用动态规划来求解最长公共子序列问题,算法这块儿比较薄弱,便想着在网上找现成的思路和代码,也算拾人牙慧,但有一点没想到,都已经22年了,关于LCS问题网上给出的答案如此一言难尽……,只有零散几篇对于 新手 来说比较友好,但也仅仅这样,好在自己花了点

    2023年04月08日
    浏览(33)
  • 两个数组的动态规划——最长公共子序列模型

    1.考虑空串,即dp表多出一行一列, 代表某个字符串为空。 2.考虑最后一个位置;是否相等; 3.可在字符串最前面加虚拟位置以对应映射关系; 4.一般横行是j,列是i。此时第一行代表第二个字符串不为空,即第一个字符串是空的 给你两个字符串  s   和  t  ,统计并返回在

    2024年03月10日
    浏览(55)
  • 动态规划应用篇:详解最长公共子序列问题

    动态规划 是一个强大的工具,将复杂问题 分解 为多个容易解决的子问题,并且会对中间结果进行存储从而避免重复计算,然后将它们的解组合起来,形成大问题的解,高效地得出 全局最优解 。前面我们已经了解了动态规划的基础知识及一维动态规划问题的求解,今天,我

    2024年04月15日
    浏览(33)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包