最长递增子序列(LIS)和最长公共子序列(LCS)

最长递增子序列(LIS)

在计算机科学中,最长递增子序列(longest increasing subsequence)问题是指,在一个给定的数值序列中,找到一个子序列,使得这个子序列元素的数值依次递增,并且这个子序列的长度尽可能地大。最长递增子序列中的元素在原序列中不一定是连续的。许多与数学、算法、随机矩阵理论、表示论相关的研究都会涉及最长递增子序列。解决最长递增子序列问题的算法最低要求O(n log n)的时间复杂度,这里n表示输入序列的规模。——百度百科


LIS的一种做法是 O ( n 2 ) O(n^2) O(n2) 的复杂度,显然效率不高。这里我记录一下 O ( n log ⁡ n ) O(n\log n) O(nlogn) 的做法。
f [ i ] f[i] f[i] 表示所有数 ( a [ i ] a[i] a[i] a [ n ] a[n] a[n] ) 组成的LIS中,所有长度为 i i i 的LIS的末尾元素中最小值。我们需要从 a [ 1 ] a[1] a[1] 遍历到 a [ n ] a[n] a[n] ,用每个数组元素更新我们的 f f f 数组。用一个变量 l e n len len ,来记录我们当前最长LIS的长度。
如果 f[len] < a[i],那么 a [ i ] a[i] a[i] 就可以接在当前最长的(长度为 l e n len len)的LIS之后,就得到一个新的更长的LIS,相应的操作就是 f[++len] = a[i]
如果 a [ i ] a[i] a[i] 不能使LIS的长度增加,那么它一定相对比较小,那么,我们是否可以用它来优化 f f f 数组呢?他总是替换 f f f 数组从左往右第一个大于它的数。换句话说,它总是接在从左往右最后一个小于它的数后面。为什么?因为如果接在大于他的数后面,就不符合LIS的定义了(LIS要递增)。但如果替换一个比它小的数,又违反了 f f f 数组的定义( f f f 数组要最小)。综上,应该替换 f f f 数组从左往右第一个大于它的数。换句话说,它总是接在从左往右最后一个小于它的数后面,这样才能对 f f f

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值