此摘录来自Cracking the Coding Interview 5th Edition
数字是随机生成的并存储在(扩展)数组中。怎么样 你会跟踪中位数吗
作者向我们介绍了基于 heap 的解决方案:
堆真的很擅长基本排序并跟踪max和 分钟。这实际上很有趣 - 如果你能跟踪它 较大的一半和较小的一半元素。更大的一半是 保持在最小堆中,使得较大的一半中的最小元素 是根源。较小的一半保持在最大堆中,使得 最小的一半的最大元素是根源。现在有了这些 数据结构,你有根的潜在中位元素。" 如果堆不再是相同的大小,您可以快速重新平衡" 通过从堆中弹出一个元素并将其推送到堆中的堆 到另一个
我对这种方法有几个问题,我一次要求他们一个人保持井井有条。 首先,使用这种方法,如果遍历数组中的元素,您如何知道特定元素属于最小堆或算法所描述的最大堆? 假设我们的数据元素是[20,39,14,7,86,90]。当你迭代数组时,你会放什么堆,比方说20?
答案 0 :(得分:2)
每次插入元素时,请检查最小堆的最小值和最大堆的最大值,以查看每个元素所属的堆。
当你看到20时,两个堆都是空的,所以没关系 - 假设在一个平局的情况下我们将元素放在较小元素的最大堆中。
[20] []
当你看到39它大于20时,所以它进入上层
[20] [39]
14低于20,因此它进入较低的堆
[14,20] [39]
7低于20,因此它进入较低的堆,但现在较低的堆太大了,所以20从较低的堆出来并进入上堆。
[7,14] [20,39]
86> 20,所以它进入上层
[7,14] [20,39,86]
90> 20,所以它进入上层堆,但现在上层堆太大了,所以20从上层堆出来并回到下层堆
[7,14,20] [39,86,90]
事情变得平衡并不重要 - 也许你应该坚持使用较低的堆大小< =上层堆大小,反之亦然 - 但你需要保持平衡。
答案 1 :(得分:0)
这是填写详细信息的一种方法。
我们维护以下不变量。
到目前为止,最小堆内容和最大堆的多集合联合是输入。
最大堆中的所有元素都不大于最小堆中的所有元素。
最小堆的大小减去最大堆的大小为零或一。
要扫描新元素,我们将其插入最小堆中。尺寸的差异现在是一两个。如果它是两个,我们从最小堆中弹出min元素并将其插入最大堆,恢复不变量3。
中位数是最小堆中的min元素或该元素的平均值以及max heap中的max元素,具体取决于大小差异是1还是零。