最长递增(减)子序列

最长递增子序列(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 .

代码实现:

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值