最长递增子序列LIS

Posted 血影雪梦

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了最长递增子序列LIS相关的知识,希望对你有一定的参考价值。

本总结是是个人为防止遗忘而作,不得转载和商用。

题目

         给定长度为N的数组A,计算A的最长的单调递增的子序列(不一定连续)。

         如:给定数组A5,6,7,1,2,8,则A的LIS为5,6,7,8,长度为4。

方法一

         使用LCS解LIS问题:

                  原数组为A 5, 6, 7, 1, 2, 8

                  排序后:A’1, 2, 5, 6, 7, 8

                  因为,原数组A的子序列顺序保持不变,而且排序后A’本身就是递增的,这样,就保证了两序列的最长公共子序列的递增特性。如此,若想求数组A的最长递增子序列,其实就是求数组A与它的排序数组A’的最长公共子序列。

         PS:LCS见http://blog.csdn.net/xueyingxue001/article/details/52916554

方法二 - 动态规划

         如果直接由An得出结论,如:根据8得出LIS为5678是不好做的,那么就把n降一将,先A0=5开始,求以5结尾的LIS,然后从A0推出A1,即:以6结尾的LIS,然后从A0和A1分别推出A2,即:以7结尾的LIS,以此类推,下面举个例子。

         求数组1, 4, 6,2, 8, 9, 7的LIS。

         假设当前已经求出了A0 ~A5:

                   A0:当前已经求出以1结尾的LIS时1,长度为1;

                   A1:以4结尾的LIS时14,长度为2;

                   A2:以6结尾的LIS为146,长度为3;

                   A3:以2结尾的LIS为12,长度为2;

                   A4:以8结尾的LIS为1468,长度为4;

                   A5:以9结尾的LIS为14689,长度为5;

         现在求Ai+1(A6),即求以7结尾的最长LIS:

                   A0->A6:将7放在1后面可以,此时长度为2;

                   A1->A6:将7放在14后面可以,此时长度为3;

                   A2->A6:将7放在146后面可以,此时长度为4;

                   A3->A6:将7放在12后面可以,此时长度为3;

                   A4->A6:将7放在1468后面不可以,因为7比8小;

                   A5->A6:同上,不行。

                   那A0->A6、A1->A6、A2->A6、A3->A6中最大的是谁呢?是A2->A6,因此A2->A6的结果1467就得到了。

         话说这题单纯肉眼就能得出结论,因此这个的更重要的意义是学习动态规划。

方法三 - 贪心法

         求数组1, 4, 6, 2, 8, 9, 7的LIS。

         1,创建一个足够大的缓冲区

         2,从左向右取:

                   第一个1放在缓冲区

                   第二个4放在缓冲区末尾,放上去后让4和前面的依次比较,如果a[i]=4> a[j],那就让a[j+1] = a[i],这里不存在此情况,所以缓冲区还是14

                   第三个6放在缓冲区末尾,然后比较,缓冲区为146

                   第四个2放在缓冲区末尾,然后比较,当2和1比较时,因为2>a[0]=1,所以令a[0+1]=2,所以缓冲区为126

                   同理把8、9、7也依次代入,最后缓冲区为12679

         3,到此所有数遍历完毕,当然现在缓冲区存留的12679不是LIS,不过!长度是LIS的长度!

         这是为什么?

         是这样,首先从左向右取的时候,146的LIS是146没问题吧,而当遍历到1462时,1462的LIS还是146,2没用,于是我就想个办法把2替换到数组中,这样数组的长度就一定是LIS的长度了(虽然内容不是LIS)

         话说,刚才在第二步介绍的比较可以用折半查找,不用一个个比较。

         再话说,当从12689得出12679时不需要知道之前的内容,所以这个本质上是贪心。


以上是关于最长递增子序列LIS的主要内容,如果未能解决你的问题,请参考以下文章

力扣:673. 最长递增子序列的个数

最长递增子序列 O(NlogN)算法

关于LIS和LCS问题的o(nlogn)解法

最长上升子序列(LIS)

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

最长递增子序列(LIS)