我正在尝试理解n log n解决方案。看起来你不必在任何给定的点存储整个临时列表,只是最后一个元素会这样做。
这是如何工作的?
我不想在现有帖子上发帖,所以创建了一个新帖子。
花了很多时间来理解它。 。 :(
答案 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)。