此问题与this类似。区别在于我有二进制Max-Heap 而不是 Min-Heap 。这使问题完全不同。
我的想法:
1)我遍历所有节点以找到第二个最小元素,这将采用O(n)
2)当我找到第二个最小的元素时,我将该元素冒泡,通过与其父元素交换直到它到达根,这将需要O(logn)
3)我从根中删除元素并获取最右边的元素并将其存储在根位置(常规堆删除操作),这将采用O(logn)
总计为O(n)+ O(logn)+ O(logn),即O(n)。
已编辑:已添加二进制
有没有比这更好的解决方案?
答案 0 :(得分:1)
为什么不保留一个包含2个元素的小数组来保留最小2个元素的副本?
然后,所有操作只能用O(1)步骤改变,你可以在恒定时间内提供答案。
答案 1 :(得分:0)
第二个最小元素是叶子或叶子的父叶子,叶子是叶子的唯一子元素。
如何删除第二个最小元素:
所以O(n)+ O(log(n))仍然是O(n),但比较较少。
答案 2 :(得分:0)
当谈到大O符号时 - 不,它不能做得更好。在最大堆中查找任意元素是O(n)
。
然而,您可以减少需要遍历1/2 * n
的最大节点数,并且基本上算法速度加倍。 [仍然是O(n)
域名],因为最大堆中的第二个最小元素最多只有一个子,所以你只能遍历叶子(其中n / 2个)和一个元素at大多数只有一个儿子。 (记住,二进制堆是一个表示完整树的数组,因此最多只有一个元素只有一个子)。
还可以增强一点删除步骤,但我怀疑它会产生什么重大影响),所以我不打算付出努力。