我在看 这个pycon谈话,34:30 并且发言者说得到了 t
列表中最大的元素 n
元素可以完成 O(t + n)
。
怎么可能?我的理解是创建堆将是 O(n)
,但是复杂性是多少? nlargest
本身就是这样 O(n + t)
要么 O(t)
(什么是实际的算法)?
我在看 这个pycon谈话,34:30 并且发言者说得到了 t
列表中最大的元素 n
元素可以完成 O(t + n)
。
怎么可能?我的理解是创建堆将是 O(n)
,但是复杂性是多少? nlargest
本身就是这样 O(n + t)
要么 O(t)
(什么是实际的算法)?
在这种情况下,发言者是错误的。实际成本是 O(n * log(t))
。仅在第一个时调用Heapify t
可迭代的元素。那是 O(t)
但如果是微不足道的话 t
比小得多 n
。然后将所有剩余的元素添加到此“小堆”中 heappushpop
, 一次一个。这需要 O(log(t))
每次调用的时间 heappushpop
。堆的长度仍然存在 t
始终。在最后,堆被分类,这是成本 O(t * log(t))
,但如果这也是微不足道的 t
比小得多 n
。
有很简单的方法可以找到预期的最大元素 O(n)
时间;例如, 看这里。在最坏的情况下,有更难的方法 O(n)
时间。然后,在输入的另一个传递中,您可以输出 t
元素> =第t大(在重复的情况下有繁琐的并发症)。整个工作 能够 完成 O(n)
时间。
但这些方式需要 O(n)
记忆也。 Python不使用它们。实际实现的优点是最坏情况下的“额外”内存负担 O(t)
当输入是例如产生很多值的发生器时,这可能是非常重要的。