【发布时间】:2013-04-11 23:38:53
【问题描述】:
我有一个具有最大元素的整数列表,我需要跟踪列表中的最大元素:
[3, 1, 2] (3 is the max)
每个时间段,我都会得到一个新的随机元素,将其添加到列表的末尾,并在恒定时间内删除列表的第一个元素。所以,在当前时间段结束时,我的列表会变成这样:
[3, 1, 2] (3 is the max)
-> [3, 1, 2, -5] (don't care about max at this moment)
-> [1, 2, -5] (now 2 is the max)
我可以保留一个优先级队列,以列表中的值为键,进行 O(log(n)) 插入和删除,但我想知道是否有更有效(可能 [摊销] 恒定时间?)的方法来做它。
【问题讨论】:
-
如果你能比
O(log(n))做得更好,我会感到惊讶 -
也许尝试在cs.stackexchange.com 上发布这个?即使 O(1) 算法是不可能的,我也会有兴趣证明这种算法是不可能的。也许一个归约论点表明,如果你有这样的方法,你可以在 O(N) 或其他的时间内实现排序。
-
您可以使用 Java 中的 ArrayList 之类的东西来跟踪每个值的出现次数(这是 Pieter Geerkens 在他的回答中建议的);这有一个丑陋的缺点,虽然 k 是列表元素绝对值的最大值,但它会占用 O(k) 空间。您可以通过使用散列结构来保持计数保持较小,这将花费您 O(n) 空间和发生计数器的摊销 (!) O(1) 时间。
-
另一方面,队列中任何一个元素的出现次数并没有真正的帮助;当最大元素的最后一次出现被删除时,您仍然需要搜索新的最大值。
-
@torquestomp:就是这样。如果您有一个数据结构,您可以在小于 log(n)(组合时间)内插入和删除项目,那么您可以比 n log n 更快地排序。我们已经知道这样做是不可能的。一些堆变体允许 O(1) 插入,但删除总是 log(n)(有时摊销)。
标签: algorithm