heapq.nlargest如何工作?

时间:2014-04-13 03:24:10

标签: python algorithm heap time-complexity

我正在查看this pycon talk, 34:30,发言人表示,t可以在n内完成O(t + n)元素列表的O(n)个最大元素。

怎么可能?我的理解是创建堆将是nlargest,但O(n + t)本身的复杂性是什么,是O(t)还是{{1}}(以及实际算法是什么)?

2 个答案:

答案 0 :(得分:14)

在这种情况下,发言人是错误的。实际费用为O(n * log(t))。仅在可迭代的第一个t元素上调用Heapify。这是O(t),但如果t远小于n,则无关紧要。然后将所有剩余的元素添加到这个"小堆"通过heappushpop,一次一个。每次调用O(log(t))需要heappushpop次。堆的长度始终为t。在最后,堆被排序,其成本为O(t * log(t)),但如果t远小于n,那么这也是微不足道的。

有趣的理论; - )

有一些相当简单的方法可以在预期的O(n)时间内找到第t个最大的元素;例如,see here。在最坏情况O(n)时间内,有更难的方法。然后,在输入的另一个传递中,您可以输出t元素> =第t个最大(在重复的情况下具有繁琐的复杂性)。因此整个工作可以在O(n)时间内完成

但这些方式也需要O(n)内存。 Python不使用它们。实际实施的一个优点是最坏的情况"额外的"内存负担是O(t),当输入是一个产生很多值的生成器时,这可能非常重要。

答案 1 :(得分:0)

它实际上是 O(n+tlog(n)) 因为 heapify 需要 O(n) 并且对于最大或最小的每个元素都需要 O(log(n))。所以对于 t 最大/最小它需要 tlog(n)。因此时间复杂度为 O(n+t*log(n))