我有一个像这样的堆(python,heapq模块)
>>> h = []
>>> heappush(h, (5, 'write code'))
>>> heappush(h, (7, 'release product'))
>>> heappush(h, (1, 'write spec'))
>>> heappush(h, (3, 'create tests'))
如何删除O(logn)中项值为“create tests”的元组并保留heap属性?
这是我能想到的(不是O(logn))
for i in range(len(h)):
if h[i][1] == "create tests":
h[i], h[-1] = h[-1], h[i]
popped = h.pop()
heapq.heapify(h)
break
如果您确实需要从
heap
中取出一个项,但希望保留heap
,则可以懒洋洋地执行该操作,并在该项自然出现时将其丢弃,而不是在列表中搜索该项。如果您将要删除的项目存储在黑名单
set
中,那么每次您heapq.heappop
检查该项目是否在set
中。如果它存在,则丢弃它并再次heappop
,直到得到未列入黑名单的内容,或者heap
为空恐怕只有heapq没有这种方法。因为从堆中搜索元素需要
O(n)
。但是您可以将它与
dict
一起使用,这样可以给O(1)
时间来搜索条目。更新:
天真的做法是:
然后,您可以通过访问这个
hdict
而不是您的O(n)
线性搜索来获取给定字符串的索引。如果多个已删除的元素具有相同的值,则黑名单集将有问题。而是使用逻辑删除计数指令来实现
heap_remove
:正如预期的那样,您已经摊销了O(1)个删除时间,并且只要您不在堆的其他位置,堆的
top
总是准确的。考虑一下这个数字列表,它们首先被推到堆中,然后按相同的顺序“移除”(而不是弹出):
按预期插入工作:
但是删除是通过增加对象的墓碑来完成的。如果堆的顶部设置了墓碑,则移除对象并减少tomstone计数器。
注意,当第二个
heap_remove(3)
被称为@GP89的解决方案时,由于3
已经在tombstone集合中而崩溃。您可以研究这个示例here。
相关问题 更多 >
编程相关推荐