最长上升子序列有o(n^2)的复杂度这个就不说了,简单易懂,博客一大堆。我们今天来说说o(nlogn)复杂度的这个方法。
以前我学习这个算法的时候,看了很多博客,楞是看了很久才看懂,所以自己今天立志要把这个算法整的简单易懂一点儿
举个例子来讲解我的思路,例如我要找的序列是【 7 2 1 5 6 4 3 8 9 】
第一步 先拿出第一个数7
然后 长度为1的序列就是【7】,我表示为如下的形式
1:【7】
第二步加入2 ,我发现2比7小,那么我就用2代替7,这样的做的目的是如果后面有一个上升序列 前面可以加个7组成更长的,那么
把7换成2效果也是一样的 ,所以我就用2替换7,结果就是
1:【2】
第三步加入1,继续替换2
1:【1】
第四步加入5,这个时候我们发现5比1大,所以我就可以扩展出长度为2的序列了,当然长度为1的序列依旧保留
1:【1】
2:【1,5】
为什么要保留长度为1的序列,是有道理的 如果这里出现的是9不是5 那么舍弃长度为1 的序列会有大麻烦
第五步加入6
发现可以加入长度为1的序列扩展,长度2的序列,但是我们有了长度2的序列并且最后一位是5比6更优,所以长度为2的序列不变,但是6加入长度为2的序列可以扩展为长度3的序列
1:【1】
2:【1,5】
3:【1,5,6】
第六步加入4 ,同理4加入长度为1的序列不能改变它但是可以改变长度为2 的
1:【1】
2:【1,4】
3:【1,5,6】
第七加入3结果是
1:【1】
2:【1,3】
3:【1,5,6】
第八加入8结果就是长度为1的序列加入8扩展为【1,8】但是【1,3】比【1,8】优秀,所以舍弃,同理长度为2的加入2得到【1,3,8】也没有同样长度为3的序列【1,5,6】优秀,所以舍弃。但加入长度为3的序列可以得到长度4的序列【1,5,6,8】
1:【1】
2:【1,3】
3:【1,5,6】
4:【1,5,6,8】
因此我们发现了规律就是每加入一个数,找到一个长度为m的序列使得这个序列 的最后一位数比它小,长度为m+1的序列的最后一位数比它大,那么就用这位数更新长度为m+1的那个序列的最后一位数。但是如果长度m的序列是当前最长的那个序列,也就是 说意味着不存在m+1长度的序列,那么直接扩展出长度加1 的一个新序列。
最后我们加入9 发现它比最长长度的那个的最后一位还大,所以直接扩展新的序列【1,5,6,8,9】
1:【1】
2:【1,3】
3:【1,5,6】
4:【1,5,6,8】
5:【1,5,6,8,9】
因此最长度长度是5。 一共遍历了n个数字,每个数字呢需要取寻找上面提到的那个长度为m的序列,可以用2分查找,因此复杂度是logn 因此整个算法复杂度是nlogn
其实仔细看看我上面的分析和别人的方法是一致的