最长递增(减)子序列

来源:互联网 发布:淘宝二手交易在哪里 编辑:程序博客网 时间:2024/05/29 08:32

最长递增子序列(LIS)DP 中的入门吧,算是。

1,复杂度O(N^2)的算法

     设DP【i】中保存的是1~i 中最长递增子序列的长度,则DP【i】=max(dp【j】)+1,并且arrary[i]>arrary[j]。最后在DP【】中找一个最大的值。

代码实现:

 

2,复杂度O(N * log N)的算法

     O(N * log N)的算法关键在于建立了一个辅助数组f【】,f【i】表示长度为 i 的递增子序列中结尾元素的最小值,用K来表示数组当前的长度,算法结束后K的值即为最长递增子序列的长度。

具体来说:

设当前已经求出的长度为K,判断arrary[i]和f[K]:

(1),如果arrary[i]>f[K],即arrary[i]大于长度为K的序列中的最后一个元素,这样就可以使序列的长度增加 1 ,即K=K+1,然后现在的f[K]=arrary[i];

(2),如果arrary[i]<f[K],那么就在f[1]....f[K]中找到最大的 j ,使得f[j]<arrary[i],所以arrary[i]大于长度为j的序列的最后一个元素,那么就可以更新长度为j+1的序列的最后一个元素,所以f[j+1]=arrary[i];

 复杂度的分析:

因为有n个元素要进行计算,又每次都要查找n次,所以复杂度是n*n,但是,注意到,f[]数组里的元素的单调递增的性质,可以用二分法查找,所以就变成了log n .

代码实现: