前言

LIS 即 longest increasing string,最长递增子序列,可以是不连续的。例如 2 3 5 2 3 4 5 的最长递增子序列为{2,3,4,5},长度为4.
两种方法可以求出,一种O(n^2)的动态规划算法,一种是O(nlogn)的二分查找算法。

动态规划算法

  • 具体思路 : 设置一个dp[i],代表以a[i]为末位的最长递增子序列的长度。其状态转换方程为 dp[i] = max(dp[i],dp[j]+1) | a[j]<a[i]
  • 核心代码:
    fori(i, 0, n){dp[i] = 1;forj(j, 0, i){if (a[j]<a[i] && dp[i]<dp[j]+1) {dp[i] = dp[j]+1;}}}

不难理解,递推出以i为结尾的LIS长度,最后dp数组里最大的即a数组LIS的长度。
举例说明:

i 0 1 2 3 4 5 6 7
a[i] 2 3 4 2 3 4 5 6

当 i = 5 时
j = 0 ,a[j] < a[i], dp[i] = max(1,1+1) = 2;
j = 1 , a[j]<a[i], dp[i]=max(2,2+1) =3;
j = 2 ,a[j] = a[i]
j = 3 ,a[j]<a[i], dp[i] = max(3,1+1) = 3;
j = 4 , a[j]<a[i], dp[i] = max(3,2+1) = 3;
通过这一个例子,大家可以看出,这是一个暴力求出以i为结尾的LIS长度的算法。

O(nlgn)算法

  • 具体思路 : 以上的算法可以看出,每次确定以i为末尾的LIS时,都是 j 遍历一遍 0-i,而这个遍历是O(n)的,所以可以用二分查找的方法简化成 lgn的复杂度。
    设定一个数组,每次读取一个a[i]都与数组的末尾一个数top比较,如果a[i] > top,则把a[i]加入数组末尾,如果a[i] < top,则从栈中找到第一个 大于a[i]的数,替换成a[i]。这样最后栈的长度就是LIS的长度。
  • 核心代码:
int find(int l, int r, int x) {                      //找出第一个>a[i]的元素,如果没有,返回lwhile (l < r) {int mid = l+(r-l) / 2;if (f[mid] < x) {l = mid + 1;} else {r = mid;}}return l;
}
int lis() {int len = 0;for (int i = 0; i < n; i++) {int k = find(0,len,a[i]);f[k] = a[i];                          //如果返回的 k = len,则代表把a[i]加入了末尾if (k == len) {                  //长度+1len++;}}return len;
}

举例说明,依旧是上面的例子 :

i 0 1 2 3 4 5 6 7
a[i] 2 3 4 2 3 4 5 6

可以通过打表看出

其中的 k = len时,len++ ,代表a[i]加入了数组的末尾。每次len都比数组f[n]的长度 多一位,在二分算法里,如果所有的元素都比a[i]小,那么k = 新加的一位,a[i] 加入f数组的末尾。

LIS 最长递增子序列相关推荐

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

    出处 http://segmentfault.com/blog/exploring/ 本章讲解: 1. LCS(最长公共子序列)O(n^2)的时间复杂度,O(n^2)的空间复杂度: 2. 与之类似但不 ...

  2. LIS 最长递增子序列问题

    一,    最长递增子序列问题的描述 设L=<a1,a2,-,an>是n个不同的实数的序列,L的递增子序列是这样一个子序列Lin=<aK1,ak2,-,akm>,其中k1< ...

  3. 数组字符串那些经典算法:最大子序列和,最长递增子序列,最长公共子串,最长公共子序列,字符串编辑距离,最长不重复子串,最长回文子串 (转)...

    作者:寒小阳 时间:2013年9月. 出处:http://blog.csdn.net/han_xiaoyang/article/details/11969497. 声明:版权所有,转载请注明出处,谢谢 ...

  4. [51Nod 1218] 最长递增子序列 V2 (LIS)

    传送门 Description 数组A包含N个整数.设S为A的子序列且S中的元素是递增的,则S为A的递增子序列.如果S的长度是所有递增子序列中最长的,则称S为A的最长递增子序列(LIS).A的LIS可 ...

  5. 51Nod-1134 最长递增子序列【LIS】

    1134 最长递增子序列 基准时间限制:1 秒 空间限制:131072 KB 分值: 0 难度:基础题 给出长度为N的数组,找出这个数组的最长递增子序列.(递增子序列是指,子序列的元素是递增的) 例如 ...

  6. 动态规划 —— 最长递增子序列(LIS)

    LIS:Longest Increasing Subseq,最长递增子序列,是不要求该子序列在原始序列中间连续存放的. 为了降低对这一问题的理解难度,既然最长递增子序列不要求子序列位置连续,我们不妨先 ...

  7. 耐心排序之最长递增子序列(LIS)

    目录 一.问题引入 1.最长递增子序列(LIS) 2.问题分析 3.代码实现 4.问题思考 二.耐心排序 1.基本介绍 2.操作步骤 3.代码实现 三.俄罗斯套娃信封问题 1.题目描述 2.问题分析 ...

  8. python最大连续递增子列_最长递增子序列(LIS)解法详述

    求数组中最长递增子序列(Longest Increasing Subsequence, LIS) LIS问题是算法中的经典题目,传统的解法是使用动态规划,时间复杂度是O(n^2):改进的方法时间复杂度 ...

  9. CCNU ACM 2016夏季集训·最长递增子序列(LIS)

    这几天dp写得难受-- 在讨论这个问题之前,首先明确:"子序列"是指从原序列中挑选出若干元素,按照原序列中的顺序组成新的序列(区别于"子串",即从原序列中挑选连 ...

最新文章

  1. 【解决方案】module 'cv2.cv2' has no attribute 'xfeatures2d'
  2. 结构体之位域全面分析
  3. eclipse中菜单Build Path的解释和设置
  4. 第四次博客作业:bookstore缺陷报告
  5. 如何查看外网ip地址_如何查看本机ip地址?
  6. 请教关于 license.licx 不能转换成2进制文件!(c# 开发web应用程序)
  7. 一张“黑洞”照片需半吨重硬盘?!
  8. vscode推荐插件的安装
  9. 2021-09-06单纯形计算方法(
  10. jaxen-1.1-beta-6.jar下载,Dom4j的xpath的使用
  11. php淘口令,淘口令使用说明
  12. 恶意软件\垃圾流氓通用反删除批处理文件
  13. 大厂智力题讲解,学它!!!!(一)
  14. DE2-115 SDRAM地址问题
  15. 大学python难不难_“大学四年怎么过?”其实是有答案的
  16. 咸鱼前端—CSS盒子模型
  17. 游戏推广中买量和导量是什么意思?
  18. MFC中关于char[]转换成LPCWSTR的问题
  19. Android 模拟手指滑动
  20. MyCat —— 性能最好的数据库中间件

热门文章

  1. 计算机专业认知存在的问题,浅谈新形势下计算机专业存在的问题与对策
  2. SpringBoot整合Elasticsearch详细步骤以及代码示例(附源码)
  3. [教程]Windows下使用Ladon批量爆破SSH弱口令
  4. 分枝定界图解(含 Real-Time Loop Closure in 2D LIDAR SLAM论文部分解读及BB代码部分解读)
  5. 失眠,开灯,看书,看数学书!
  6. 基于H5canvas和js的高斯模糊处理
  7. 走过一片麦田,只能摘一次,并且不能回头,如何保证摘到的麦穗尽可能大
  8. word文档中显示目录结构、插入目录
  9. java计算机毕业设计志愿者管理系统演示录像2020源码+mysql数据库+系统+lw文档+部署
  10. shell获取当前目录和当前文件名和当前目录的路径