最长公共子序列(上海交通大学考研机试题)

题目描述

给出两个长度为 n 的整数序列,求它们的最长公共子序列(LCS)的长度,保证第一个序列中所有元素都不重复。

注意:

第一个序列中的所有元素均不重复。

第二个序列中可能有重复元素。

一个序列中的某些元素可能不在另一个序列中出现。

输入样例

bash 复制代码
5
2 1 3 8 7
2 9 3 4 5

输入样例

bash 复制代码
2

数据范围

1 ≤ n ≤ 1 0 6 1≤n≤10^6 1≤n≤106, 序列内元素取值范围 1 , 1 0 6 1,10\^6 1,106

分析

此题的数据量达到了1e6故不能用传统的 o ( n 2 ) o(n^2) o(n2)的dp做法,需考虑 o ( n l o g n ) o(nlogn) o(nlogn)的做法。

由于第一个序列中元素不重复,这是一个典型的最长公共子序列转换为最长上升子序列问题。


最长上升子序列求法 O ( n l o g n ) O(nlogn) O(nlogn)

首先我们看看最长公共子序列的求解过程是什么样子的?

A: 2 1 3 8 7
B: 2 9 3 4 5

ans = {2, 3};

就是从B中按照下标从小到大的顺序(从左至右)去A中找相同的数字,且在A中数字的下标也需要是递增的(也需要从左至右)

我们用另一种方式模拟这个过程

① 我们先将A中的数字和下标存储在idx数组中idx[key] = value,key 对应的是A中的值,value对应的是A中元素值对应的下标;

② 再按照坐标序遍历B中的元素,找到其在A中的位置idx[key], 找到一个我们就处理这个元素的下标到f数组中,将f数组维护为递增数组(刚刚我们说到A,B的子序列下标都需要是递增的);

f 数组维护的是B数组元素在A数组元素中的下标

时间复杂度

O ( n l o g n ) O(nlogn) O(nlogn)

C++ 代码

c 复制代码
#include <bits/stdc++.h>

using namespace std;

const int N = 1e6 + 7;

int idx[N], f[N];
int cnt;
int n;

int find(int x) {
    int l = 0, r = cnt;
    while (l < r) {
        int mid = l + r >> 1;
        if (f[mid] >= x) r = mid;
        else l = mid + 1;
    }
    
    return l;
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(0);
    
    cin >> n;
    memset(idx, -1, sizeof idx);
    
    for (int i = 1; i <= n; i ++ ) {
        int x;
        cin >> x;
        idx[x] = i;     // 记录数组中每个值的下标是多少
    }
    
    
    for (int i = 1; i <= n; i ++ ) {
        int x;
        cin >> x;
        
        int k = idx[x];
        if (k == -1) continue;
        
        if (k > f[cnt]) f[ ++ cnt ] = k;    // 如果当前下标大于f数组末尾元素下标就直接加入f数组
        else {
            int p = find(k);    // 找到大于等于k的第一个数的下标
            f[p] = k;           // 将下标的对应值替换掉
        }
    }
    
    cout << cnt << endl;
    return 0;
}
相关推荐
酉鬼女又兒17 天前
零基础入门计算机网络运输层:端到端通信核心作用、端口号分类规则、复用分用工作机制及UDP与TCP协议全方位对比详解
网络·网络协议·tcp/ip·计算机网络·考研·udp·php
小马哥crazymxm18 天前
Arxiv论文周选 (2026-W24)
论文阅读·人工智能·考研
酉鬼女又兒19 天前
零基础入门计算机网络网际层核心:IP数据报发送与转发完整流程、静态路由配置方法、路由环路成因与解决方案及历年考研经典例题深度解析
网络·tcp/ip·计算机网络·考研·职场和发展
酉鬼女又兒19 天前
零基础入门IPv4地址:从基本概念、分类编址、子网划分到无分类编址与应用规划全解
网络·网络协议·计算机网络·考研·职场和发展·分类·智能路由器
killerbasd20 天前
总结 6.13
考研
05候补工程师21 天前
【408考研复习】数据结构核心笔记:字符串模式匹配与内部排序算法全解析
数据结构·经验分享·笔记·考研·算法·排序算法
乘~风22 天前
408考研-计组-1.2计算机系统层次结构笔记+1.3计算机性能指标
笔记·考研·408
killerbasd22 天前
总结 6.11
考研
唐维康22 天前
F00403综合程序设计考什么?昆工891复试全流程拆解
考研
2601_9618454223 天前
高考真题试卷电子版|2025高考全科试卷分类下载
考研·面试·蓝桥杯·远程工作·程序员创富·高考