我正在审查决赛并且偶然发现了以下问题:
二进制堆默认情况下具有优先级队列语义:如果我们插入一些元素n次,我们需要在它“消失”之前将其删除n次。想象一下,你想要用set语义实现二进制堆。在这种情况下插入和移除操作的速度有多快?
(a)插入:O(n)删除:O(logn)
(b)insert:O(log n)remove:O(n)
(c)insert:O(log n)remove:O(log n)
(d)插入:O(1)去除:O(n2)
(e)以上都不是。
要插入使用优先级队列语义实现的堆,它将是O(logn),因此将删除。但是对于集合,插入和删除取决于集合本身的许多因素。您认为答案应该是什么?
答案 0 :(得分:2)
我想说插入:O(n)删除:O(log n)。在一个集合中,不允许重复项目,并且应该忽略尝试插入重复项目,因为堆是完全填充的二叉树(底部除外),如果要插入到集合中,则搜索(项目)如果你发现它你什么都不做插入,所以插入可能需要O(n)进行查找和插入(你最多可以渗透n次)。 deleteMin具有o(log n)时间复杂度
答案 1 :(得分:2)
set semantics 引用的内容并不完全清楚,但作者可能意味着属性
A∪{x}∪{x} =A∪{x}
即。添加已在集合中的元素应该没有(可观察的)效果。
执行此操作的直接方法是在插入时检查重复项。但是,在普通的二进制堆中,删除任意元素需要O(n),这显然是相当慢的。
更聪明的想法可能是在删除最小元素时消除重复,重复删除直到我们看到新值。这需要O(k log n),其中k是检索节点的重复数。如果已知k是常数,则为O(log n)。然而,在最坏的情况下,k = n,使得最坏情况时间复杂度为O(n log n)。但是,如果我们测量的是分摊的时间复杂度,则该算法可以实现插入和移除的O(log n)。
通过使用平衡二叉搜索树而不是堆,可以实现插入和删除的最坏情况时间复杂度O(log n)。这是否符合" heap"目前尚不清楚。
总之,可能的答案是:
也就是说,根据我们解释问题的方式,不同的答案是正确的。