【问题标题】:how to get the max heap in python如何在python中获得最大堆
【发布时间】:2018-06-23 15:53:58
【问题描述】:

我在python中使用heapq模块,我发现我只能最小堆,即使我使用reverse=True

我仍然得到最小的顶部堆

from heapq import *

h=[]
merge(h,key=lambda e:e[0],reverse=True)
heappush(h, (200, 1))
heappush(h, (300,2))
heappush(h, (400,3))
print(heappop(h))

我还是得到了结果:

(200, 1)

我想得到结果:

(400,3)

怎么做?

这是最小的元素。我要弹出最大的元素?

ps:这是问题的一部分,找到最大值,然后分成几个元素,然后将其放回堆中。

【问题讨论】:

  • nlargest(h, 1)?
  • @cᴏʟᴅsᴘᴇᴇᴅ 写max(h)的方式很糟糕。

标签: python heap max-heap


【解决方案1】:

为什么不使用PriorityQueue 对象?您可以存储(priority,key) 元组。制作最大堆的一种简单解决方案是使 prioritykey 相反:

from Queue import PriorityQueue
pq = PriorityQueue()
for i in range(10): # add 0-9 with priority = -key
    pq.put((-i,i))
print(pq.get()[1]) # 9

【讨论】:

  • pq没有弹出功能
  • 不确定你的意思。 PriorityQueueget() 函数等效于堆的 pop():它删除并返回最高优先级元素
  • 对不起,我以为会删除之前优先级最高的元素。谢谢你。
  • 我可以使用索引轻松获得第二大数
  • 怎么样?在最大堆中,根是最大的元素(因此您确定最大元素在索引 0 中),但第二大元素可以是根的任何一个子元素(因此它可以在索引 1 或索引 2 中)。如果您确定在任何给定时间想要最大的 2 个元素,我同意您可以有效地做到这一点:h[0] 是最大的,max(h[1],h[2]) 是第二大的。跨度>
【解决方案2】:

The documentation 说,

我们的 pop 方法返回最小的项目,而不是最大的(称为 教科书中的“最小堆”; “最大堆”在文本中更常见,因为 就地分拣的适用性)。

所以你不能直接获得最大堆。但是,间接获得它的一种方法是将项目的 negative 推送到堆上,然后在弹出项目后再次获取负数。所以你执行heappush(h, (-200, -1)),而不是heappush(h, (200, 1))。并弹出并打印最大项目,执行

negmaxitem = heappop(h)
maxitem = (-negmaxitem[0], -negmaxitem[1])
print(maxitem)

还有其他方法可以获得相同的效果,具体取决于您在堆中存储的确切内容。

请注意,在最小堆中尝试h[-1] 无法找到最大项——堆定义并不能保证最大项最终会出现在列表的末尾。 nlargest 应该可以工作,但时间复杂度为 O(log(n)),仅检查最小堆中的最大项目,这违背了堆的目的。我的方法在负堆中有时间复杂度O(1) 来检查最大的项目。

【讨论】:

  • 我不明白你在说什么nlargest。要找到你给它的可迭代的最大元素,它需要 O(n),而不是 O(log(n))。
  • 其实根据文档,我觉得其实是O(n log n): "Equivalent to: sorted(iterable, key=key, reverse=True)[:n]"
  • @NiemaMoshiri 这意味着相同的结果,不同的复杂性。顺便说一句,你刚才说要求它获取最大的 n=1 个元素需要 O(0) 时间。
  • 啊,不知道这只是意味着输出是等价的,而不是时间复杂度。感谢那!另外,不确定您所说的 O(0) 时间是什么意思。 Big-O 时间复杂度是对 n 接近无穷大时渐近运行时可伸缩性的描述;你不只是插入 n 的值
  • @NiemaMoshiri 我当然可以插入 n 值。 Big-O 复杂度是“对于 all n ≥ n₀ 语句”。对于 n=n₀ 也是如此。我可以插那个。您没有说出您的想法 n₀,所以我假设 n=1,因为我们正在讨论找到 1 个最大值。但这并不重要。无论你的 n₀ 是什么,我都可以选择 n=n₀,然后 O(n log n) = O(n₀ log n₀) = O(1)。你仍然说它是恒定的时间,这是错误的。
猜你喜欢
  • 2021-07-01
  • 1970-01-01
  • 1970-01-01
  • 2012-11-23
  • 1970-01-01
  • 1970-01-01
  • 2018-09-30
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多