最长上升子序列 II 时间复杂度(nlogn)
题目:最长上升子序列 II
给定一个长度为 N 的数列,求数值严格单调递增的子序列的长度最长是多少。
输入格式
第一行包含整数 N。
第二行包含 N个整数,表示完整序列。
输出格式
输出一个整数,表示最大长度。
数据范围
1≤N≤100000,
−10e9≤数列中的数≤10e9
输入样例:
7
3 1 2 1 8 5 6
输出样例:
4
问题解决
这个问题我用dp+二分法的方法来写。
一、 遍历a[i]将a[i]放入dp数组
1.1构造dp[i]数组:
dp[i]为长度是i的上升子序列结尾元素。
i:表示子序列的长度,取值范围是1~len,其中len表示目前最大的子序列长度。
1.2 将a[i]放入dp数组中
规则为找到某个dp[j],使得a[i]>dp[j]&&a[i]<dp[j+1],
找到后将dp[j+1]替换为a[i],更新len 判断len是否因dp数组的扩大而变大,len=max(len,j+1)。
...........................................................................................................................................................................................................
二 、在dp[1]和dp[len]之间寻找满足1.2条的位置
2.1 L端起点和r端终点的初始选择
因为dp[i]的取值范围是1~len所以起始边界设置在两端之外L=0,r=len+1;
2.2 退出二分的条件
当L+1==r时说明两个指针已经相邻,边界已经找到即可退出循环。
2.3 L端和r端分界线的判定条件
L端都<a[i],r端都>=a[i],满足l端条件L=mid,否则r=mid。
2.4 采用r
r即为1.2中的j+1。
我用的是手写二分法,主要参考链接如下:
https://www.bilibili.com/video/BV1d54y1q7k7?from=search&seid=14378360076371462119
大家也可以用upper_bound来取得r值。
3 总结
该程序时间复杂度为O(n*log n),可以解决n=1e5的规模的问题。
程序君:
#include<bits/stdc++.h>
using namespace std;
const int N=1e5;
const int inf=1e9;
int main()
{
int a[N],dp[N],n;
cin>>n;
for(int i=1;i<=n;i++) scanf("%d",&a[i]);
int len=0;
for(int i=1;i<=n;i++)
{
int l=0,r=len+1;
while(l+1!=r)
{
int m=l+r>>1;
if(dp[m]<a[i])
{
l=m;
}
else
{
r=m;
}
}
dp[r]=a[i];
len=max(len,r);
}
cout<<len;
return 0;
}
最长上升子序列 II 时间复杂度(nlogn)的更多相关文章
- 最长递增子序列 LIS 时间复杂度O(nlogn)的Java实现
关于最长递增子序列时间复杂度O(n^2)的实现方法在博客http://blog.csdn.net/iniegang/article/details/47379873(最长递增子序列 Java实现)中已 ...
- HDU 5748 最长上升子序列的长度nlogn(固定尾部)
Bellovin Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others)Total ...
- 最长上升子序列(LIS)n2 nlogn算法解析
题目描述 给定一个数列,包含N个整数,求这个序列的最长上升子序列. 例如 2 5 3 4 1 7 6 最长上升子序列为 4. 1.O(n2)算法解析 看到这个题,大家的直觉肯定都是要用动态规划来做,那 ...
- AcWing 896. 最长上升子序列 II
#include<iostream> #include<algorithm> #include<vector> using namespace std; int m ...
- 最长上升子序列O(nlogn) 要强的T^T(2358)
题目来源:http://www.fjutacm.com/Problem.jsp?pid=2358 要强的T^T TimeLimit:1000MS MemoryLimit:65536K 64-bit ...
- BZOJ 3173 [Tjoi2013] 最长上升子序列 解题报告
这个题感觉比较简单,但却比较容易想残.. 我不会用树状数组求这个原排列,于是我只好用线段树...毕竟 Gromah 果弱马. 我们可以直接依次求出原排列的元素,每次找到最小并且最靠右的那个元素,假设这 ...
- [ An Ac a Day ^_^ ] HDU 1257 基础dp 最长上升子序列
最近两天在迎新 看来只能接着水题了…… 新生培训的任务分配 作为一个有担当的学长 自觉去选了动态规划…… 然后我觉得我可以开始水动态规划了…… 今天水一发最长上升子序列…… kuangbin有nlog ...
- LIS最长上升子序列O(n^2)与O(nlogn)的算法
动态规划 最长上升子序列问题(LIS).给定n个整数,按从左到右的顺序选出尽量多的整数,组成一个上升子序列(子序列可以理解为:删除0个或多个数,其他数的顺序不变).例如序列1, 6, 2, 3, 7, ...
- (转载)最长递增子序列 O(NlogN)算法
原博文:传送门 最长递增子序列(Longest Increasing Subsequence) 下面我们简记为 LIS. 定义d[k]:长度为k的上升子序列的最末元素,若有多个长度为k的上升子序列,则 ...
- 最长递增子序列 O(NlogN)算法
转自:点击打开链接 最长递增子序列,Longest Increasing Subsequence 下面我们简记为 LIS. 排序+LCS算法 以及 DP算法就忽略了,这两个太容易理解了. 假设存在一个 ...
随机推荐
- String常用API
String常用API 1. 获取字符串长度 int length = str.length(); 2. 根据索引,返回字符串中对应的字符 char c = str.chaeAt(length-1); ...
- Sqlite 安装操作使用
一.什么是 SQLite 数据库 SQLite 是嵌入式SQL数据库引擎.与大多数其他 SQL 数据库不同,SQLite 没有单独的服务器进程.SQLite 直接读取和写入普通磁盘文件.具有多个表,索 ...
- 定位java程序中占用cpu最高的线程堆栈信息
找出占用cpu最高的线程堆栈信息 在java编码中,有时会因为粗心导致cpu占用较高的情况,为了避免影响程序的正常运行,需要找到问题并解决.这里模拟一个cpu占用较高的场景,并尝试定位到代码行. 示例 ...
- c++题目:数迷
c++题目:数迷 题目 [题目描述] 给出含有N×N个格子的正方形表格,要求每个格子都填上一个个位数(范围1-N),使得每行.每列以及同一斜线上的数字都不同.部分格子已经填好数字.求满足题意的方案数. ...
- Mybatis SQL 对应Oracle中javaType和jdbcType对应
<resultMap type="java.util.Map" id="resultjcm"> <result property=" ...
- Sqoop的介绍和安装
sqoop下载地址:https://share.weiyun.com/woVbfnfS 或者 https://archive.apache.org/dist/sqoop/1.99.7/ Sqoop简介 ...
- 数电第7周周结_by_yc
一.通用双向移位寄存器: 功能描述: 4位的双向移位寄存器,含控制输入端(ctrl).串行输入端(Dsl.Dsr).4个并行输入端和4个并行输出端,要求实现5种功能:异步置零.同步置数.左移.右移 ...
- 疫情可视化part3
前言 之前在part2中说的添加自定义主题配色已经开发完成了,除此之外我还添加了一些的3d特效. 前期文章 这是part1的文章:https://blog.csdn.net/xi1213/articl ...
- 【十次方微服务后台开发】Day02:加密与JWT鉴权、微服务注册中心、配置中心、熔断器、网关、消息总线、部署与持续集成、容器管理与监控Rancher、influxDB、grafana
一.密码加密与微服务鉴权JWT 1.BCrypt密码加密 Spring Security 提供了BCryptPasswordEncoder类,实现Spring的PasswordEncoder接口使用B ...
- 【JVM实战系列】「监控调优体系」实战开发arthas-spring-boot-starter监控你的微服务是否健康
前提介绍 相信如果经历了我的上一篇Arthas的文章[[JVM实战系列]「监控调优体系」针对于Alibaba-Arthas的安装入门及基础使用开发实战指南]之后,相信你对Arthas的功能和使用应该有 ...