输出最长递增子序列

article/2025/9/21 0:12:32

目录

题目:

输入描述:

输出描述:

示例1

输入

输出

示例2

输入

输出

说明

备注:

思路分析:

改进:

得到最长子序列:

易错点:

代码展示:


题目:

给定数组arr,设长度为n,输出arr的最长递增子序列。(如果有多个答案,请输出其中字典序最小的)

输入描述:

输出两行,第一行包括一个正整数n(n<=100000),代表数组长度。第二行包括n个整数,代表数组arr 。 (1 ≤ arr[i] ≤ 1e9)

输出描述:

输出一行。代表你求出的最长的递增子序列。

示例1

输入

9 2 1 5 3 6 4 8 9 7

输出

1 3 4 8 9

示例2

输入

5 1 2 8 6 4

输出

1 2 4

说明

其最长递增子序列有3个,(1,2,8)、(1,2,6)、(1,2,4)其中第三个字典序最小,故答案为(1,2,4)

备注:

时间复杂度O(NlogN),空间复杂度O(N)。

思路分析:

  1. 由递增子序列,可以知道该序列是依赖与前面序列,且连续性要求较高
    1. 所以dp[i]存储的值是以array[i]元素结尾时的最优解,即最长递增子序列
  2. dp[i]点最长子序列依赖于所有array[小于i的值]的dp[]值中的最大值
    1. 比如array = {1,3,5,4,6,5,7}
    2. dp[]的前三位是{1,2,3} 则第dp[3],
    3. 查到array[0]
    4. 而dp[1]>dp[0] 所以将dp[3]赋值为dp[1]+1,因为前三位中有个长度为2的序列的结尾数比array[3]小
  3. 依次更新dp,找到dp的最大值,即为最长递增子序列的长度

改进:

  1. 每次求dp都要遍历一次array的前面部分,导致时间复杂度时O(N^2)
  2. 但是之前的array与dp已经遍历过了,现在我们要做的是将其中重要的信息存储起来
    1. 重要信息:长度为0/1/2/3的子序列,最小要以什么array结尾
    2. 每次dp的更新就不需要去遍历所有array,
      1. 需要查找到合适的结尾数,在其基础上将序列长度加一。并根据当前dp,array更新“重要信息”
    3. 序列长度,与结尾数的映射一定是单调递增的,所以,查找时,可以用二分查找,或者用有序表来组织(ceilingKey()方法)

得到最长子序列:

  1. 根据dp,dp存储的是以dp[i]结尾时的最长子序列长度,
  2. 那么倒序遍历dp,当dp[i]的值等于len,len-1,len-2....时说明是最长子序列的最小字典序

易错点:

  1. 在用有序表TreeMap时,如果要将(键1,值1)替换成(键2,值1),不能单纯使用replace,put方法,要先remove(键1,值1),再put(键2,值1)

代码展示:

import java.io.*;
import java.util.TreeMap;public class Main{public static void main(String[] args)throws IOException{BufferedReader read = new BufferedReader(new InputStreamReader(System.in));int n = Integer.parseInt(read.readLine());String[] str = read.readLine().split(" ");int dp[] = new int[n];//以array[i]结尾的序列的最长长度int array[] = new int[n];for(int i=0;i<n;i++){array[i] = Integer.parseInt(str[i]);dp[i] = 0;}int max = 0;//最长子序列长度int flag = 0;//当前最长序列TreeMap<Integer,Integer> map = new  TreeMap<Integer,Integer>();//(长度为i的最小结尾数, 序列长度i)for(int i=0;i<n;i++){Integer key = map.ceilingKey(array[i]);if(key == null){//没找到ceiling,说明当前array是最大的,添加一个键值对,序列长度加1map.put(array[i],++flag);dp[i] = flag;}else{//找了,更新,(键1,值1)替换成(键2,值1)dp[i] = map.get(key);map.remove(key);map.put(array[i],dp[i]);}max = Math.max(max, dp[i]);}//System.out.println(max);String sout = "";for(int j = n-1;j>=0;j--){//倒序遍历,遇到len,len-1,len-1...将其加入字符串if(dp[j] == max){sout =  array[j]+" "+sout ;max--;}}System.out.print(sout);}
}


http://chatgpt.dhexx.cn/article/F6pFVDmk.shtml

相关文章

NC91 最长递增子序列

NC91 最长递增子序列 这道题n的范围是1e5&#xff0c;因此不能使用常规的dp[i]&#xff0c;表示以i结尾的最大的子序列&#xff0c;因为这个时间复杂度是n方级别。因此要换一种算法。 贪心二分&#xff0c;时间复杂度为O(nlogn) 下面说说贪心二分的解法&#xff0c;举例说明基…

Vue3 最长递增子序列详解

Vue3 最长递增子序列研究 本文初衷 彻底讲清楚 Vue3 源码中实现最长递增子序列的算法。 概念名词 **最长递增子序列&#xff1a;**在一个给定的数值序列中&#xff0c;找到一个子序列&#xff0c;使得这个子序列元素的数值依次递增&#xff0c;并且这个子序列的长度尽可能地…

Java 最长递增子序列_最长递增子序列问题 Java

最长递增子序列问题 LIS(longest increasing subsequence) 例如 给定一个数列&#xff0c;长度为N&#xff0c; 求这个数列的最长上升(递增)子数列(LIS)的长度. 以 1, 7, 2, 8, 3, 4 为例。 这个数列的最长递增子数列是 1 2 3 4&#xff0c;长度为4&#xff1b; 次长的长度为3&…

最长递增子序列

问题 给定一个长度为N的数组,找出一个最长的单调自增子序列(不一定连续,但是顺序不能乱)。例如:给定一个长度为6的数组A{5, 6, 7, 1, 2, 8},则其最长的单调递增子序列为{5,6,7,8},长度为4. 解法1:最长公共子序列法 这个问题可以转换为最长公共子序列问题。如…

动态规划设计方法详解最长递增子序列

很多读者反应&#xff0c;就算看了前文动态规划详解&#xff0c;了解了动态规划的套路&#xff0c;也不会写状态转移方程&#xff0c;没有思路&#xff0c;怎么办&#xff1f;本文就借助「最长递增子序列」来讲一种设计动态规划的通用技巧&#xff1a;数学归纳思想。 最长递增…

最长递增子序列(Longest Increasing Subsequence)

定义 最长上升子序列&#xff08;Longest Increasing Subsequence&#xff0c;LIS&#xff09;&#xff0c;在计算机科学上是指一个序列中最长的单调递增的子序列。 问题描述 给定一个长度为 N 的数组&#xff0c;找出一个最长的单调自增子序列&#xff08;不一定连续&#…

最长递增子序列问题(你真的会了吗)

目录 一.最长递增子序列问题I 二.最长递增子序列问题II 三. 最长递增子序列问题III 一.最长递增子序列问题I 1.对应牛客网链接 最长上升子序列(一)_牛客题霸_牛客网 (nowcoder.com) 2.题目描述&#xff1a; 3.解题思路 1.首先我们分析题意&#xff1a;最长递增子序列拆&#x…

UDP协议详细解析

一、基本概念 基本定义&#xff1a;UDP 是User Datagram Protocol的简称&#xff0c; 中文名是用户数据报协议&#xff0c;是OSI&#xff08;Open System Interconnection&#xff0c;开放式系统互联&#xff09; 参考模型中一种无连接的传输层协议&#xff0c;提供面向事务的…

tcp read 和 udp recvfrom

udp中写一个长度为0的数据报是可行的&#xff0c;这导致一个包含IP头部、udp头部和没有数据的IP数据报。这也意味着对于数据报协议&#xff0c;recvfrom返回0值也是可行的&#xff1a;它不表示对方已经关闭了连接&#xff0c;这与tcp套接口上read返回0值的情况不同。由于udp是无…

UDPTCP

目录 Socket 一.UDP 特点 基于UDP实现回显服务器 服务器 客户端 端口冲突 图解 二.TCP 特点 基于TCP实现回显服务器 服务器 客户端 图解 Socket Socket套接字&#xff0c;是由系统提供用于网络通讯的技术&#xff0c;是基于TCP/IP协议的网络通信的基本操作单元&#xff0c;基于…

Reliable UDP

Reliable UDP&#xff08;可靠的UDP&#xff09;是一套服务品质的增强&#xff0c;比如拥挤控制调整&#xff0c;数据重传&#xff0c;薄化服务器算法等&#xff0c;这些增强可以提高服务器在数据包丢失和网络拥挤的条件下向RTP客户表现品质良好的RTP流的能力。Reliable UDP’的…

TCP /UDP

TCP与UDP工作在传输层&#xff0c;在程序之间传数据&#xff08;视频&#xff0c;聊天&#xff0c;图片&#xff0c;网页&#xff09; TCP基于连接的&#xff0c;可靠的&#xff08;及时知对方接受/拒绝&#xff0c;是否传错&#xff09;&#xff08;文本&#xff0c;网页&…

UDP、TCP

传输层协议UDP、TCP 一、TCP/UDP的任务二、UDP1.UDP概述2.UDP报文格式3.使用UDP的应用层协议 三、TCP1.TCP概述2.TCP报文3.TCP三次握手4.四次挥手5.超时重传6.流量控制和快重传7.拥塞控制8.延迟应答、捎带应答9.粘包问题10.基于TCP的应用层协议 四、总结 一、TCP/UDP的任务 我们…

tcp udp proxy

服务目的 首先如下图所示&#xff1a; 作为一个内外网的通信&#xff0c;必须使用tcp 和 udp 的proxy 把内网和外网打通&#xff0c;比如中间是一个有两个网卡的路由器&#xff0c;打通以后&#xff0c;由proxy 发送数据到服务端&#xff0c;服务端按照上图处于外网。 服务端…

UDP-RTP协议解析

一、RTP协议 数据传输协议RTP&#xff0c;用于实时传输数据。RTP报文由两部分组成&#xff1a;报头和有效载荷 二、RTP的会话过程 当应用程序建立一个RTP会话时&#xff0c;应用程序将确定一对目的传输地址。目的传输地址由一个网络地址和一对端口组成&#xff0c;有两个端口&a…

UDP 理解

这里需要指出的一点是&#xff0c;伪首部完全是虚拟的&#xff0c;它并不会和用户数据报一起被发送出去&#xff0c;只是在校验和的计算过程中会被使用到&#xff0c;伪首部主要来自于运载UDP报文的IP数据报首部&#xff0c;将源IP地址和目的IP地址加入到校验和的计算中可以验证…

关于TCP/UDP

目录 1、TCP协议 1.1 TCP协议格式 1.2 TCP协议原理 2、UDP协议 在学习TCP/UDP之前先来了解以下整体的通信传输&#xff0c;它是一个向下封装、向上分用的过程&#xff1a; 这是TCP/IP四层模型&#xff0c;所以要想实现通讯&#xff0c;通过TCP建立和断开连接是至关重要的&a…

UDP详解

1、UDP数据包格式 UDP 是User Datagram Protocol的简称&#xff0c; 中文名是用户数据报协议&#xff0c;是OSI&#xff08;Open System Interconnection&#xff0c;开放式系统互联&#xff09; 参考模型中一种无连接的传输层协议&#xff0c;提供面向事务的简单不可靠信息传…

TCPUDP相关介绍

TCP and UDP TCP&#xff08;Transmission Control Protocol&#xff0c;传输控制协议&#xff09;是面向连接的协议&#xff0c;也就是说&#xff0c;在收发数据前&#xff0c;必须和对方建立可靠的连接。 一个TCP连接必须要经过三次握手才能建立起来。断开连接需要四次挥手才…

TCPUDP

TCP&#xff1a;面向连接的服务&#xff0c;可靠的进程到进程的通信协议。&#xff08;因为TCP里面封装了端口号&#xff0c;端口号就意味着一个服务&#xff0c;进程&#xff09;&#xff1b;应用场景&#xff1a;如&#xff1a;文件传输&#xff1b;HTTP应用层协议 UDP&…