logn的最长公共子序列

最长公共子序列nlogn算法 求两个序列的最大公共子序列(LCS),普遍的动态规划算法时间复杂度为O(n^2),在两个序列的长度很长的时候运行时间过长。可以转化为最长上升子序列(LIS)来求,时间复杂度可以优化到nlogn。1.首先说一下转化为LIS的方法:  找到s1序列中每个元素在s2序列中的位置,并用这些在s2中的位置替换s1中对应的元素,注意s1中的元素在s2中当有多个位置(a1,a2,a3……)时,要降序排列(a1>a 阅读详情

最长公共子序列(LCS)最常见的算法是时间复杂度为O(n^2)的动态规划(DP)算法,但在James W. Hunt和Thomas G. Szymansky 的论文”A Fast Algorithm for Computing Longest Common Subsequence”中,给出了O(nlogn)下限的一种算法。
定理:设序列A长度为n,{A(i)},序列B长度为m,{B(i)},考虑A中所有元素在B中的序号,即A某元素在B的序号为{Pk1,Pk2,..},将这些序号按照降序排列,然后按照A中的顺序得到一个新序列,此新序列的最长严格递增子序列即对应为A、B的最长公共子序列。
举例来说,A={a,b,c,d,b},B={b,c,a,b},则a对应在B的序号为2,b对应序号为{3,0},c对应序号为1,d对应为空集,生成的新序列为{2,3, 0, 1, 3, 0},其最长严格递增子序列为{0,1,3},对应的公共子序列为{b, c, b}

实现代码:(洛谷P1439):

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<vector>
#include<cstring>
#include<string>
using namespace std;
const int N=1000005;
vector<int>v[N],a,d;
int main()
{
    int n,i,j,A[N],B[N];
    cin>>n;
    for(i=1;i<=n;i++)scanf("%d",&A[i]);
    for(i=1;i<=n;i++)scanf("%d",&B[i]);
    for(i=n;i;i--)
        v[B[i]].push_back(i);//保证后面a中的序列是按照B中从前往后的顺序出现,所以要倒序
    for(i=1;i<=n;i++){
        int now=A[i];
        if(v[now].empty())continue;
        for(int j=0;j<v[now].size();j++)//将A中的数按在B中出现的顺序加入a
            a.push_back(v[now][j]);
    }
    if(!a.empty()){//logn的最长上升子序列
        d.push_back(a[0]);
        for(i=1;i<a.size();i++){
            if(a[i]>d.back())d.push_back(a[i]);
            else{
                vector<int>::iterator iter=lower_bound(d.begin(),d.end(),a[i]);
                *iter=a[i];
            }
        }
    }
    cout<<d.size()<<endl;

    return 0;
}

字符串版:

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<vector>
#include<string>
#include<cstring>
using namespace std;
vector<int>v[30],a,d;
int main()
{
    freopen("test.in","r",stdin);
    freopen("zj.out","w",stdout);
    int n;string str1,str2;
    cin>>n;getchar();getline(cin,str1);getline(cin,str2);
    for(int i=str2.size()-1;i>=0;i--)v[str2[i]-'a'].push_back(i);
    for(int i=0;i<n;i++){
        int now=str1[i]-'a';
        if(v[now].empty())continue;
        for(int j=0;j<v[now].size();j++)
            a.push_back(v[now][j]);
    }
    if(!a.empty()){
        d.push_back(a[0]);
        for(int i=0;i<a.size();i++){
            if(a[i]>d.back())d.push_back(a[i]);
            else{
                vector<int>::iterator iter=lower_bound(d.begin(),d.end(),a[i]);
                *iter=a[i];
            }
        }
    }
    cout<<d.size()<<endl;

    return 0;
}

附:朴素o(n2)的最长公共子序列:

#include<cstdio>
#include<iostream>
#include<string>
#include<algorithm>
#include<cstring>
using namespace std;
int f[200005][200005];
int main()
{
    freopen("test.in","r",stdin);
    freopen("bl.out","w",stdout);
    int n,i,j,k;
    string str1,str2;
    cin>>n;getchar();getline(cin,str1);getline(cin,str2);
    //if(str1[0]==str2[0])f[0][0]=1;
    for(i=0;i<n;i++){
        for(j=0;j<n;j++){
            if(str1[i]==str2[j])f[i][j]=max(f[i][j],((i==0||j==0)?0:f[i-1][j-1])+1);
            else{
                f[i][j]=max(f[i][j],max(i==0?0:f[i-1][j],j==0?0:f[i][j-1]));
            }
        }
    }
    cout<<f[n-1][n-1]<<endl;

    return 0;
}
面试题 | 求两个字符串的最长公共子串 要求时间复杂度O(nm),空间复杂度O(1) 来源:牛客网-编程题 题意:给定两个字符串str1和str2,输出两个字符串的最长公共子串,如果最长公共子串为空,输出-1。 思路: 用动态规划空间复杂度会是 O(nm)O(nm)O(nm),我们发现计算每一个 f[i][j]f[i][j]f[i][j] 的时候只需要计算f[i−1][j−1]f[i-1][j-1]f[i−1][j−1],所以只要按照斜线方向(遍历 n + m - 1条斜线)计算所有的值,用一个变量维护最大值,那么空间复杂度就可以降低到 O(1)O(1)O(1) 核心:知道如何遍历 n + 阅读详情

相关推荐

Windows下Python调用D435i相机避坑指南:从SDK版本选择到RealSense Viewer报错解决

本文详细介绍了在Windows环境下使用Python调用Intel D435i相机的完整避坑指南。重点解决了SDK版本选择问题,推荐使用稳定的Intel RealSense SDK 2.54.2版本,并提供了从环境配置、常见报错解决到实际应用案例的全流程实践指导,帮助开发者高效完成相机部署与开发。

palm99的专栏 924

数据结构与算法之最长公共子串

最长公共子串问题是指给定两个字符串S1和S2,求它们的公共子串中最长的那一个。其实就是求两个字符串的最长重复子串。最朴素的算法就是枚举S1和S2的每一对子串,然后判断它们是否相等,时间复杂度是O(n^3)。但是这种算法效率太低,无法满足实际需求。一般采用动态规划的思想进行求解,令dp[i][j]表示以S1的前i个字符和S2的前j个字符为结尾的公共子串的长度,当S1[i]=S2[j]时,dp[i][j]=dp[i-1][j-1]+1;否则dp[i][j]=0。最后找出dp[i][j]的最大值即可。

weixin_47225948的博客 4925

行人重识别技术(Re-ID)概述、研究现状以及相关数据集下载

ReID技术概述什么是ReID一般流程Re-ID特点研究现状难点数据集reid常用数据集以及下载链接评价指标实现思路研究方式基于表征学习基于度量学习基于局部特征全局特征切片姿态基于视频序列RQEN基于GANCamStyleDG-NetGAN总结对比未来方向建议文献 什么是ReID 行人重识别是指利用计算机视觉技术,判断在不同时间段、不同监控下出现的行人图像是否属于同一人员的技术。行人重识别是最近几年在视频分析领域下热门的研究领域,可以看做是人脸识别应用的拓展。现在大街上的监控较多,由于设备质量、成像光线、.

留缘的博客 1万+

算法设计 - LCS 最长公共子序列&&最长公共子串 &&LIS 最长递增子序列

本章讲解: 1. LCS(最长公共子序列)O(n^2)的时间复杂度,O(n^2)的空间复杂度; 2. 与之类似但不同的最长公共子串方法。 最长公共子串用动态规划可实现O(n^2)的时间复杂度,O(n^2)的空间复杂度;还可以进一步优化,用后缀数组的方法优化成线性时间O(nlogn);空间也可以用其他方法优化成线性。 3.LIS(最长递增序列)DP方法可实现O(n^2)的时间复杂度,进一步优化最佳可达到O(nlogn) 一些定义: 字符串 X, Y 长度 分别m,n 子串:字符串S的子串r[i,...,j.

zhaoxiaoba的博客 1268

Vivado实战:UltraScale/UltraScale+器件eFUSE寄存器配置与安全编程全解析

本文详细解析了Xilinx UltraScale/UltraScale+器件中eFUSE寄存器的配置与安全编程方法。从芯片唯一身份标识到加密密钥烧录,再到用户寄存器的灵活应用和安全控制寄存器的配置技巧,全面介绍了如何利用eFUSE功能提升硬件安全性。文章还提供了JTAG接口安全管理和NKZ文件备份方案,帮助开发者避免常见陷阱,确保安全编程的可靠性。

weixin_42535703的博客 428

别再只设接触压力了!用ANSYS Workbench模拟O型圈密封泄漏的完整流程

本文详细介绍了在ANSYS Workbench中模拟O型圈密封泄漏的完整流程,重点解析了流体渗透压力载荷的设置与应用。通过双物理场耦合模型和精确的参数配置,帮助工程师准确评估密封性能,避免传统方法仅考虑接触压力的局限性。文章还提供了常见问题的解决方案和工程实践建议,提升密封设计的可靠性。

weixin_30372371的博客 400

lcs 最长公共子序列 O(nlogn)算法

最长公共子序列问题: 给定2个字符串,求其最长公共子串。如abcde和dbada的最长公共字串为bd。 动态规划:dp[i][j]表示A串前i个和B串前j个的最长公共子串的长度。 则 若A[i] == B[j] , dp[i][j] = dp[i-1][j-1] + 1; 否则 dp[i][j] = max(dp[i-1][j],dp[i][j-1]); 时间复杂...

weixin_34161029的博客 684

ICESat-2数据下载的两种方法

ICESat-2数据下载

weixin_46341898的博客 2899

Prince and Princess (最长公共子序列n*logn)

Prince and PrincessInput: Standard InputOutput: Standard OutputTime Limit: 3 SecondsIn an n x n chessboard, Prince and Princess plays a game. The squares in the chessboard are numbered 1, 2, 3 ... n*n...

a1046765624的博客 1616

基于YOLOv8/YOLOv7/YOLOv6/YOLOv5的农作物害虫检测系统(深度学习模型+UI界面+训练数据集)

随着人工智能技术在农业领域的深入应用,基于深度学习的害虫检测系统已成为智慧农业的重要组成部分。本文详细介绍了一种基于YOLOv8/YOLOv7/YOLOv6/YOLOv5的农作物害虫检测系统,涵盖算法原理、数据集构建、模型训练、系统实现及完整代码。该系统能够实时检测并识别多种农作物害虫,为农业生产提供精准的病虫害监测解决方案。

YOLO 273

070、人脸AE实战:基于人脸检测的亮度优先与背光补偿算法

本文分享了基于人脸检测的亮度优先与背光补偿算法的实战经验。针对逆光自拍场景下人脸过曝问题,作者提出了动态平衡方案: 通过内缩20%的人脸核心区域提取亮度,避免背景干扰 创新性地采用"亮度差+置信度"的背光判定机制 设计动态权重分配策略,人脸权重可在30%-70%间调整 引入平滑处理防止亮度跳变,补偿增益限制在1.5倍以内 关键点在于:不是简单提亮人脸,而是通过分析人脸与背景亮度差,在80-110目标亮度范围内动态调整,实现自然的人脸曝光效果。算法已在实际项目中验证,解决了传统AE在逆光场景下的失效问题。

zzfmlxs的博客 33

最长公共子序列 LCS n*logn算法

LCS 最长公共子序列 //n*logn

m0_74039681的博客 316

BLDC&PMSM电机控制器硬件设计工程(一)概述&需求&规划

这里是一个专注于电机控制器硬件工程的开放社区与知识仓库。我们的核心使命是分享、交流与共创,致力于解开无刷直流电机(BLDC)和永磁同步电机(PMSM)中、大功率控制器硬件设计,包括驱动IC选型,电流传感器选型,控制IC,母线电容计算,功率模块(IGBT、MOS管)选型以及大功率功率模块驱动电源设计。功率等级: 重点关注中等功率(如500W-10kW) 并向大功率(10kW以上) 延伸,探讨对应的功率器件(如MOSFET, IGBT, SiC)选型与驱动。

小幽余生不加糖 637

Prince and Princess UVA - 10635 (n*logn 的最长公共子序列)

思路:求两个串的最长公共子序列,将其转化成求最长上升子序列。 转化方法:将第一个串按顺序编号,将第二个串HASH,然后求hash后的串的最长上升子序列。 代码: #include &lt;bits/stdc++.h&gt; using namespace std; const int maxn=1e5+7; const int inf=0x3f3f3f3f; typedef long lo...

untilyouydc 203

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

算法:最长公共子序列(做法小计)

给出长度为n的数组a,长度为m的数组b,求解其最长公共子序列

m0_73755253的博客 832

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

LCS 最长公共子序列

前言 LCS(longest common string)最长公共子序列 我学习的时候经历了从一般的O(n2)复杂度,数组开maxn* maxn; 用滚动数组优化空间; LCS转化成LIS,时间复杂度O(logn)。本次也按照这个顺序进行叙述。 一般的O(n2)算法 int dp[maxn][maxn]; mem(dp,0); for (int i = 0; i &l...

彤云望月 206

13.最长公共子序列

线性DP

weixin_60869516的博客 308

[DP_LIS] UVA10635

神奇的LCS和LIS的关系

Aria461863631的博客 411

LIS,LCS,一道LIS题

LCS,最长公共子序列,根据算导的推论,可以得到如下公式: c[ i ][ j ] = 0  (i = 0或j = 0) c[ i ][ j ] = c[ i-1 ] [ j-1 ] + 1 (i,j>0且xi = yj) c[ i ][ j ] = max (c [ i ][ j-1 ],c [ i-1 ][ j ])  (i , j>0且 xi≠yj ) 自己根据算导敲了下:(感觉时间

qq_33216593的博客 404

POJ 2533 Longest Ordered Subsequence (LIS DP)

最长公共自序列LIS 三种模板,但是邝斌写的好像这题过不了 N*N 1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 using namespace std; 5 const int N = 41000; 6 int a[1010],dp[1010...

weixin_30613343的博客 55

【模板】最长公共子序列 详细解析

中下标比当前元素小,因为不用差分,考虑使用树状数组维护比某下标小的 dp 最大值,此时查询满足条件的时间复杂度变为。观察朴素 dp,我们要求的便是在当前元素下标之前的最大 dp 值,即之前的元素在。解释:如果我们要从之前的序列转移过来,那么一定要满足当前元素的下标在。中都要分别在被转移的元素后面,时间复杂度为。首先考虑朴素的 dp,记。,总时间复杂度优化为。

jiangdongzhen的博客 311

Common Subsequence(DP求LCS)

题意:求两字符串最长公共子序列长度 先假设字符串起点为1,好讲些。dp[i][j]表示字符串1的前i字符和字符串2的前j个字符的最长公共子序列长度,下面我们来推到一下状态转移方程 if (arr1[i] == arr2[j]) dp[i][j] = dp[(i - 1)][(j - 1)] + 1; 为什么是由dp[i-1][j-1]转移,而不是dp[i-1][j]或dp[i][j-1]呢?因为如果arr[i]==arr[j]时,必定有dp[i][j]>da[i-1][j-1],但不一定有dp[i][

donnameの博客 207

UVA10635 Prince and Princess(LIS)

题意:王子和公主同时从1出发走到 n*n, 求他们两个路径的最长公共子序列; 思路:因为这题n有250,如果用LCS负责度为O(n^2),容易超时,于是我们选择它的优化版Lis算法来求最长公共子序列,这样我们的复杂度就降为O(n*logn)了。 Lis算法:      先回顾经典的O(n^2)的动态规划算法,设A[t]表示序列中的第t个数,F[t]表示从1到t这一段中以t结尾的最长上升子序列

Yedl的专栏 960

最长上升子序列+最长公共子序列

最长上升子序列参考——时间复杂度:动态规划O(n^2)、贪心+二分O(n*log n) 最长公共子序列参考——动态规划O(n*m)

weixin_43563311的博客 122

动态规划总结

经典问题: 一、最长上升子序列:      问题描述如下:  设L=是n个不同的实数的序列,L的递增子序列是这样一个子序列Lin=,其中k1 a[n] 则存在长度为1的不下降子序列a[n-1]或者a[n]。  有了以上的思想,DP方程就呼之欲出了(这里是顺序推的,不是逆序的): DP[I]=MAX(1,DP[J]+1)  J=0,1,...,I-1  但这样的想法实现起来是)O(n^2)

独行无疆的博客 304

【洛谷P1439】最长公共子序列

链接 (N方过百万是lsh的事,和我css有什么关系。) 两个序列的最长公共子序列,一定是这个样子的(此处样例,不唯一): 然后给映射一下,很容易发现,公共子序列的映射结果一定是上升的。 于是乎就把问题转化成了求最长上升子序列。 这里有一个log(n)的求法: f[len]表示长度为len的上升子序列的结尾。 在dp时,如果大于结尾,就把他加到末尾; 如果小于结尾,就在前面二分...

Sakura_Chiyo的博客 362
上一篇: (模板)卡时间
下一篇: 关于__int128
HumveeA6
博客等级 码龄17年 12粉丝 175原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值