前几天做题遇到求LIS的题,照常用dp去做结果超时了。之后就去网上找了O(nlogn)的方法。因为看了好几个博客我才看懂,所以这里我进行下总结。

首先第一种写法:

假设存在一个序列d[1..9] = 2 1 5 3 6 4 8 9 7,可以看出来它的LIS长度为5。
下面一步一步试着找出它。
我们定义一个序列B,然后令 i = 1 to 9 逐个考察这个序列。
此外,我们用一个变量Len来记录现在最长算到多少了

首先,把d[1]有序地放到B里,令B[1] = 2,就是说当只有一个数字2的时候,长度为1的LIS的最小末尾是2。这时Len=1

然后,把d[2]有序地放到B里,令B[1] = 1,就是说长度为1的LIS的最小末尾是1,d[1]=2已经没用了,很容易理解吧。这时Len=1

接着,d[3] = 5,d[3]>B[1],所以令B[1+1]=B[2]=d[3]=5,就是说长度为2的LIS的最小末尾是5,很容易理解吧。这时候B[1..2] = 1, 5,Len=2

再来,d[4] = 3,它正好加在1,5之间,放在1的位置显然不合适,因为1小于3,长度为1的LIS最小末尾应该是1,这样很容易推知,长度为2的LIS最小末尾是3,于是可以把5淘汰掉,这时候B[1..2] = 1, 3,Len = 2

继续,d[5] = 6,它在3后面,因为B[2] = 3, 而6在3后面,于是很容易可以推知B[3] = 6, 这时B[1..3] = 1, 3, 6,还是很容易理解吧? Len = 3 了噢。

第6个, d[6] = 4,你看它在3和6之间,于是我们就可以把6替换掉,得到B[3] = 4。B[1..3] = 1, 3, 4, Len继续等于3

第7个, d[7] = 8,它很大,比4大,嗯。于是B[4] = 8。Len变成4了

第8个, d[8] = 9,得到B[5] = 9,嗯。Len继续增大,到5了。

最后一个, d[9] = 7,它在B[3] = 4和B[4] = 8之间,所以我们知道,最新的B[4] =7,B[1..5] = 1, 3, 4, 7, 9,Len = 5。

于是我们知道了LIS的长度为5。

!!!!! 注意。这个1,3,4,7,9不是LIS,它只是存储的对应长度LIS的最小末尾。有了这个末尾,我们就可以一个一个地插入数据。虽然最后一个d[9] = 7更新进去对于这组数据没有什么意义,但是如果后面再出现两个数字 8 和 9,那么就可以把8更新到d[5], 9更新到d[6],得出LIS的长度为6。

然后应该发现一件事情了:在B中插入数据是有序的,而且是进行替换而不需要挪动——也就是说,我们可以使用二分查找,将每一个数字的插入时间优化到O(logN)~~~~~于是算法的时间复杂度就降低到了O(NlogN)~!

在理解第一种写法的基础上看第二种写法:

数组array:1 3 4 9 15 2 3 9
第0次:处理array[0]
数组f:0
数组pre:-1
第1次:处理array[1]
数组f:0 1
数组pre:-1 0
第2次:处理array[2]
数组f:0 1 2
数组pre:-1 0 1
第3次:处理array[3]
数组f:0 1 2 3
数组pre:-1 0 1 2
第4次:处理array[4]
数组f:0 1 2 3 4
数组pre:-1 0 1 2 3
第5次:处理array[5]
数组f:0 5 2 3 4
数组pre:-1 0 1 2 3 0
第6次:处理array[6]
数组f:0 5 6 3 4
数组pre:-1 0 1 2 3 0 5

第7次:处理array[7]

数组f:0 5 6 7 4

数组pre:-1 0 1 2 3 0 5 6

数组f的最后位置的内容为最长子序列值的末尾值的在array中的下标,以此为起点来重构出子序列。

通过观察很容易发现第一种写法的B数组直接存储数,而第二种写法的F数组存储的是下标,当然第一种好写但是如果要输出找到的LIS则必须用第二种。

而第二种写法中的pre数组存储的就是每个数的前接数下标。

例题及代码:HDU - 3998 Sequence

O(nlogn) 求LIS(Longest Increasing Subsequence)方法的总结相关推荐

  1. 【Lintcode】076.Longest Increasing Subsequence

    题目: Given a sequence of integers, find the longest increasing subsequence (LIS). You code should ret ...

  2. The Longest Increasing Subsequence (LIS)

    传送门 The task is to find the length of the longest subsequence in a given array of integers such that ...

  3. Dynamic Programming之Longest Increasing Subsequence (LIS)问题

    Longest Increasing Subsequence(LIS)问题是一类常见的可使用Dynamic Programming解决的算法问题.这个问题是指在一个数字序列中,找到最大个数升序排列的子 ...

  4. leetcode(300)—— Longest Increasing Subsequence(最长递增子序列)

    参考 Python 解法: 动态规划 -- 最长递增子序列(LIS) 原题位置:Longest Increasing Subsequence | LeetCode OJ 题目的说明: 严格递增: 子序 ...

  5. HPU第三次积分赛-D:Longest Increasing Subsequence(DP)

    Longest Increasing Subsequence 描述 给出一组长度为n的序列,a1​,a2​,a3​,a4​...an​, 求出这个序列长度为k的严格递增子序列的个数 输入 第一行输入T ...

  6. [Swift]LeetCode673. 最长递增子序列的个数 | Number of Longest Increasing Subsequence

    ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★ ➤微信公众号:山青咏芝(shanqingyongzhi) ➤博客园地址:山青咏芝(https://www.cnblog ...

  7. C++longest increasing subsequence 最长递增子序列的实现之二(附完整源码)

    C++longest increasing subsequence 最长递增子序列的实现 C++longest increasing subsequence 最长递增子序列的的实现完整源码(定义,实现 ...

  8. C++longest increasing subsequence 最长递增子序列的实现之一(附完整源码)

    C++longest increasing subsequence 最长递增子序列的实现 C++longest increasing subsequence 最长递增子序列的的实现完整源码(定义,实现 ...

  9. [leetcode] 300. Longest Increasing Subsequence (Medium)

    题意: 求最长增长的子序列的长度. 思路: 利用DP存取以i作为最大点的子序列长度. Runtime: 20 ms, faster than 35.21% of C++ online submissi ...

最新文章

  1. 学生计算机屏幕坏了怎么办,如果计算机显示器的屏幕坏了怎么办?
  2. 箭头函数中的this的使用
  3. 一个用于分页的page类
  4. python的socket模块_Python socket模块方法实现详解
  5. linux用户不能su: This account is currently not available
  6. Linux下静态库和动态库的编译连接
  7. java并发编程实战阅读总结(b)
  8. 基于应用层自身反远程线程注入的研究
  9. iOS蓝牙BLE4.0通信功能
  10. SAP License:SAP系统合规性审计介绍
  11. (超详细)2022年最新版java 8( jdk1.8u321)安装教程
  12. python爬虫面试代理池_Python爬虫代理池搭建的方法步骤
  13. 报错Ordinal parameter not bound
  14. python用函数绘制椭圆_Python学习笔记——opencv绘制椭圆
  15. url请求和ajax请求作用于minui treegrid的区别
  16. 怎么拍照识别植物的名称呢?教大家一个识别小妙招
  17. markdown支持的脑图工具
  18. char、char*和char**区别与联系(入门级)
  19. 自定义组件的behaviors笔记
  20. Jmeter阶梯压测聚合报告分阶梯汇总显示

热门文章

  1. 【ArcGIS微课1000例】0038:注记(Annotation)的使用方法
  2. equals == equals(null) ==null区别
  3. 5G+AI+大数据+IoT如何改变一切?
  4. iOS 直播类APP开发流程
  5. 计算机无法识别ipad2,iTunes无法识别iPad mini怎么办【解决方法】
  6. DBA系列-推荐书籍(中文版本)
  7. (一)OSG初学者入门基础教程
  8. 苹果cms双端模板安装设置教程
  9. 新浪财经50ETF期权和上交所300ETF期权行情接口
  10. Vertica资源池