algorithm - 找到最长的递增序列

标签 algorithm lis

给定一个数字序列,您需要从给定的输入中找到最长的递增子序列(不一定是连续的)。

我找到了指向此 ( Longest increasing subsequence on Wikipedia ) 的链接,但需要更多解释。

如果有人能帮助我理解 O(n log n) 实现,那将非常有帮助。如果您能举例说明该算法,我们将不胜感激。

我也看了其他帖子,我不明白的是: 大号 = 0 对于 i = 1, 2, ... n: 二进制搜索最大正 j ≤ L 使得 X[M[j]] < X[i](或者如果不存在这样的值则设置 j = 0) 上面的语句,从哪里开始二分查找?如何初始化M[]、X[]?

最佳答案

一个更简单的问题是找到最长递增子序列的长度。您可以先专注于理解该问题。该算法的唯一区别是它不使用 P 数组。

x 是一个序列的输入,所以可以初始化为: x = [0, 8, 4, 12, 2, 10, 6, 14, 1, 9, 5, 13, 3, 11, 7, 15]

m 跟踪迄今为止找到的每个长度 的最佳子序列。最好的是具有最小结束值的那个(允许在它之后添加更大范围的值)。长度和结束值是每个子序列唯一需要存储的数据。

m 的每个元素代表一个子序列。对于m[j]

  • j 是子序列的长度。
  • m[j] 是子序列最后一个元素的索引(在 x 中)。
  • 因此,x[m[j]] 是子序列最后一个元素的值。

L 是迄今为止找到的最长子序列的长度。 m 的前 L 个值是有效的,其余未初始化。 m 可以从第一个元素为 0 开始,其余元素未初始化。 L随着算法的运行而增加,m的初始化值个数也随之增加。

这是一个示例运行。 x[i],并在每次迭代结束时给出 m(但使用序列的值而不是索引)。

每次迭代中的搜索都是寻找放置 x[i] 的位置。它应该尽可能向右(以获得最长的序列),并且大于其左侧的值(因此它是一个递增的序列)。

 0:  m = [0, 0]        - ([0] is a subsequence of length 1.)
 8:  m = [0, 0, 8]     - (8 can be added after [0] to get a sequence of length 2.)
 4:  m = [0, 0, 4]     - (4 is better than 8. This can be added after [0] instead.)
 12: m = [0, 0, 4, 12] - (12 can be added after [...4])
 2:  m = [0, 0, 2, 12] - (2 can be added after [0] instead of 4.)
 10: m = [0, 0, 2, 10]
 6:  m = [0, 0, 2, 6]
 14: m = [0, 0, 2, 6, 14]
 1:  m = [0, 0, 1, 6, 14]
 9:  m = [0, 0, 1, 6, 9]
 5:  m = [0, 0, 1, 5, 9]
 13: m = [0, 0, 1, 5, 9, 13]
 3:  m = [0, 0, 1, 3, 9, 13]
 11: m = [0, 0, 1, 3, 9, 11]
 7:  m = [0, 0, 1, 3, 7, 11]
 15: m = [0, 0, 1, 3, 7, 11, 15]

现在我们知道有一个长度为 6 的子序列,以 15 结尾。子序列中的实际值可以通过在循环期间将它们存储在 P 数组中找到。

检索最佳子序列:

P 为每个数字存储最长子序列中的前一个元素(作为 x 的索引),并随着算法的推进而更新。例如,当我们处理 8 时,我们知道它在 0 之后,所以将 8 在 0 之后的事实存储在 P 中。您可以像链表一样从最后一个数字向后工作以获得整个序列。

因此对于每个数字,我们都知道它之前的数字。要找到以 7 结尾的子序列,我们查看 P 并看到:

7 is after 3
3 is after 1
1 is after 0

所以我们有子序列 [0, 1, 3, 7]。

以 7 或 15 结尾的子序列共享一些数字:

15 is after 11
11 is after 9
9 is after 6
6 is after 2
2 is after 0

所以我们有子序列 [0, 2, 6, 9, 11] 和 [0, 2, 6, 9, 11, 15](最长递增子序列)

关于algorithm - 找到最长的递增序列,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4938833/

相关文章:

algorithm - 使用 O(log(n)) 实现最近向量搜索算法

java - 仅使用 '+' ,'*' 和括号判断是否可以从给定集合中获得数字的算法

c# - 从对象列表中获取具有最大值的对象的最有效方法

c++ - O(NlogN) 或 O(Nlog^2N) 中坐标值的 LIS

algorithm - 循环最长递增子序列

c++ - 长度为 k 的递增子序列数

algorithm - 谁能解释清楚Left-Lean-Red-Black树的删除?

arrays - 数数1s 和 0s 没有比较

algorithm - 有没有办法遍历所有平衡位向量?

c++ - r值参数确实是函数范围内的l值参数吗?