【动态规划算法】【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


时间复杂性

  • 由于每个数组单元的计算耗费 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] + 1else:dp[i][j] = max(dp[i - 1][j], dp[i][j - 1])# 构造最长公共子序列lcs = ''i, j = m, nwhile i > 0 and j > 0:if str_1[i - 1] == str_2[j - 1]:lcs = str_1[i - 1] + lcsi -= 1j -= 1elif dp[i - 1][j] > dp[i][j - 1]:i -= 1else:j -= 1return lcsstr_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})

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/832388.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

银行卡实名认证API接口快速对接

银行卡实名认证API接口又叫银行卡核验类API接口、银行卡验证类API接口、银联核验类API接口,根据入参字段不同,分银行卡二要素验证API接口,银行卡三要素验证API接口,银行卡四要素验证API接口。其中,银行卡二要素验证API接口是验证开…

BeanUtils工具类中的copyProperties方法

1.两个包下BeanUtils.copyProperties对比 BeanUtils工具类主要通过导入org.springframework.beans.BeanUtils或者org.apache.commons.beanutils.BeanUtils包来获取,但是不同包中BeanUtils的方法是不一样的,让我们通过实例看看这两者的不同之处吧。 …

BEV下统一的多传感器融合框架 - FUTR3D

BEV下统一的多传感器融合框架 - FUTR3D 引言 在自动驾驶汽车或者移动机器人上,通常会配备许多种传感器,比如:光学相机、激光雷达、毫米波雷达等。由于不同传感器的数据形式不同,如RGB图像,点云等,不同模态…

AHB---原子性

1. 单拷贝原子性大小 单拷贝原子性大小定义了一个传输被保证以原子方式更新的数据字节数。 单拷贝原子性大小是为一组通信组件定义的。例如: 一个处理器、一个数字信号处理器(DSP)和一个动态随机存取存储器(DRAM)控…

TypeError报错处理

哈喽,大家好,我是木头左! 一、Python中的TypeError简介 这个错误通常表示在方法调用时,参数类型不正确,或者在对字符串进行格式化操作时,提供的变量与预期不符。 二、错误的源头:字符串格式化…

动力电池热管理方案介绍与发展方向

摘要 随着电动汽车的快速发展,高性能的动力电池系统成为推动电动汽车产业发展的重要因素。然而,伴随着能量密度提高和放电深度增加,电池热管理问题逐渐凸显。良好的热管理方案能够提高电池的寿命,保障电池性能,延长电…

【C语言刷题系列】移除元素

目录 一、问题描述 二、解题思路 三、源代码 个人主页: 倔强的石头的博客 系列专栏 :C语言指南 C语言刷题系列 一、问题描述 二、解题思路 在C语言中,原地移除数组中所有等于特定值的元素并返回新长度的问题可以通过双指针法…

Linux:进程信号(一)信号的产生

目录 一、信号是什么? 二、Linux信号 三、信号处理方式 四、信号的产生 1、 通过终端按键产生信号 2、调用系统函数向进程发信号 3、 硬件异常产生信号 一、信号是什么? 在生活中,有许多信号,比如红绿灯,下课铃声…

ChatGPT搜索引擎要来了,但它面临的麻烦还不少 | 最新快讯

界面新闻记者 | 陈振芳 界面新闻编辑 | 宋佳楠 新晋人工智能霸主OpenAI开始挑战搜索市场格局。 OpenAI很可能推出基于ChatGPT技术的新搜索引擎。5月6日,界面新闻注意到,名为“GPT Search”的网页已经上线,但目前只有会员才能访问。 上述消息…

机器人感知导读

系列文章目录 提示:这里可以添加系列文章的所有文章的目录,目录需要自己手动添加 TODO:写完再整理 文章目录 系列文章目录前言【传感器sensor】机器人/无人驾驶常用传感器模型、选型与安装车道线检测&交通信号识别&车辆实时检测【目标检测与定位…

TCP连接请求为什么要有三次握手?两次不行吗?

在TCP/IP网络协议中,三次握手是建立可靠的会话连接的一个重要机制。三次握手的过程确保了双方(客户端和服务器)都能确认彼此的接收和发送能力是否正常。这一过程不仅用于同步双方的初始序列号,还确保了连接的可靠性和数据的完整性…

后缀字串排序

直接sort: #include <iostream> #include <cstring> #include <algorithm> #include <vector>using namespace std;int main() {string str;cin >> str;int len str.size();vector<string> strings;for(int i 0; i < len; i){strin…

文件删了,回收站清空了怎么恢复?文件恢复软件一览

在日常生活和工作中&#xff0c;我们常常会遇到误删除文件的情况&#xff0c;有时甚至会因为清空了回收站而无法找回这些文件。这些文件可能包含重要的工作数据、个人照片或其他珍贵的回忆。那么&#xff0c;在这种情况下&#xff0c;我们该如何恢复这些被删除且清空回收站的文…

Java学习-练习试用Java实现求素数

以下是使用Java语言试着编写的求1-100内的素数的程序&#xff1a; public class PrimeNumbers {public static void main(String[] args) {System.out.println("Prime numbers between 1 and 100 are:");for (int i 2; i < 100; i) {if (isPrime(i)) {System.ou…

【数字图像处理笔记】Matlab实现图像平滑算法 均值-中值-高斯滤波 (三)

&#x1f48c; 所属专栏&#xff1a;【数字图像处理笔记】 &#x1f600; 作  者&#xff1a;我是夜阑的狗&#x1f436; &#x1f680; 个人简介&#xff1a;一个正在努力学技术的CV工程师&#xff0c;专注基础和实战分享 &#xff0c;欢迎咨询&#xff01; &#x…

二手车买卖求购置换租车微信抖音小程序开源版开发

二手车买卖求购置换租车微信抖音小程序开源版开发 二手车置换平台小程序系统&#xff0c;为买家和卖家提供了一个交流和交易的平台 Uniapp&#xff0c;基于Uniapp开发&#xff0c;仅支持编译微信小程序和抖音小程序 车辆发布&#xff0c;自主发布车辆信息。 圈子交流&#xff…

ubuntu20.04通过minio配置FTP服务

项目需求&#xff1a;原来存储文件用的是oss服务存储的&#xff0c;本地minio服务。因为项目需求需要ftp服务来访问文件。查看了一下minio官网4.20版本以后的支持ftp服务。官网介绍如下&#xff1a; 参考文章地址如下&#xff1a;File Transfer Protocol (FTP/SFTP) — MinIO …

五种主流数据库:窗口函数

SQL 窗口函数为在线分析系统&#xff08;OLAP&#xff09;和商业智能&#xff08;BI&#xff09;提供了复杂分析和报表统计的功能&#xff0c;例如产品的累计销量统计、分类排名、同比/环比分析等。这些功能通常很难通过聚合函数和分组操作来实现。 本文比较了五种主流数据库实…

Activity去掉默认动画效果

Activity无论是否设置style主题&#xff0c;默认都是有动画效果的。如果要去掉默认的动画效果&#xff0c;只需要在原有主题的基础上添加一个属性&#xff1a;windowAnimationStyle&#xff0c;并设置为null即可。具体步骤如下&#xff1a; 1. styles.xml中添加主题&#xf…

发电机保护系统工作原理及作用

发电机保护系统工作原理及作用 发电机保护是发电机的安全运行对保证电力系统的正常工作和电能质量起着决定性的作用&#xff0c;同时发电机本身也是十分贵重的电气设备&#xff0c;因此&#xff0c;应该针对各种不同的故障和不正常工作状态&#xff0c;装设性能完善的继电保护装…