最长的非递减序列 - n log n?

时间:2014-08-30 20:18:22

标签: algorithm

我正在尝试理解n log n解决方案。看起来你不必在任何给定的点存储整个临时列表,只是最后一个元素会这样做。

这是如何工作的?

我不想在现有帖子上发帖,所以创建了一个新帖子。

花了很多时间来理解它。 。 :(

1 个答案:

答案 0 :(得分:3)

  

您不必在任何给定点存储整个临时列表,只需要最后一个元素即可。

首先,回想一下O(n 2 )解决方案:你设置了一个数组L,它在每个元素i处具有最长非递减子序列的长度结束于元素A的{​​{1}}。这是一个例子:

i

现在想象一下设置一个数组A: 2 5 7 3 8 2 9 6 9 L: 1 2 3 2 4 2 5 3 6 ,它在每个索引M存储k的元素,该元素结束长度为A的最长非递减子序列。以下是k每个步骤的显示方式(短划线M显示未填写的地方)

-

手动完成示例以了解填充数组M (step 0) - - - - - - - - - M (step 1) 2 - - - - - - - - M (step 2) 2 5 - - - - - - - M (step 3) 2 5 7 - - - - - - M (step 4) 2 3 7 - - - - - - M (step 5) 2 3 7 8 - - - - - M (step 6) 2 2 7 8 - - - - - M (step 7) 2 2 7 8 9 - - - - M (step 8) 2 2 6 8 9 - - - - M (step 9) 2 2 6 8 9 9 - - - 的机制。

现在是关键观察:在每一步,M按非递减顺序排序。直觉上,这是明确的,因为否则较大的数字可以附加到较长的序列,并向上移动到数组M

这使您可以构建算法:

  • 存储已填写的M的最后一个位置maxPos
  • 当您到达M时,请在A[i]中针对应放置M[0..maxPos]的地方运行二进制搜索
  • 如果您最终位于数组的中间,请将旧值替换为A[i]
  • 如果元素大于或等于目前为止添加到min(A[i], oldValue)的所有元素,请将M添加到结尾,然后增加A[i]

很容易看出上面的算法是O(n * log(n)),因为它的每个maxPos步都使用二进制搜索,即log(n)。