【问题标题】:How to identify the elements that belong to the max heap and the elements that belong to the min heap?如何识别属于最大堆的元素和属于最小堆的元素?
【发布时间】:2015-02-25 02:10:30
【问题描述】:

这段摘自Cracking the Coding Interview 5th Edition

数字是随机生成并存储在(扩展)数组中的。如何 你会跟踪中位数吗

作者带我们了解了一个基于heaps的解决方案:

堆非常擅长基本排序和跟踪最大和 分钟。这实际上很有趣 - 如果您可以跟踪 较大的一半和较小的一半元素。较大的一半是 保存在最小堆中,使得较大一半中的最小元素 是根。较小的一半保存在最大堆中,这样 最小一半的最大元素在根。现在有了这些 数据结构,你在根部有潜在的中值元素。” 如果堆大小不再相同,您可以快速“重新平衡” 通过从堆中弹出一个元素并将其推送到堆 另一边

我有几个关于这种方法的问题,我一次问一个问题,以保持其井井有条。 首先,使用这种方法,如果您遍历数组中的元素,您如何知道特定元素属于算法描述的最小堆或最大堆? 假设我们的数据元素是 [20, 39, 14, 7, 86, 90]。当你迭代数组时,你会放什么堆,比如说 20?

【问题讨论】:

    标签: java arrays algorithm sorting heap


    【解决方案1】:

    每次插入元素时,检查最小堆的最小值和最大堆的最大值,以查看每个元素属于哪个堆。

    当您看到 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)的属性,但是是的。
    • 但是如果数据集是奇数,你会不会有一个 int 计数器并遍历最大堆和最小堆直到你碰到那个计数器?
    • ...不,如果数据集是奇数,则您的一个堆比另一个大一个元素。如果下堆比上堆大,那么中值就是该堆中的最大元素;否则它是来自上堆的最小元素。
    • 是的,迭代也是 O(N)。低效
    【解决方案2】:

    这是填写详细信息的一种方法。

    我们维护以下不变量。

    1. 到目前为止,最小堆和最大堆的内容的多集并集是输入。

    2. 最大堆中的所有元素不大于最小堆中的所有元素。

    3. 最小堆的大小减去最大堆的大小为零或一。

    为了扫描一个新元素,我们将它插入到最小堆中。现在大小的差异是一两个。如果是 2,我们从最小堆中弹出最小元素并将其插入最大堆,恢复不变量 3。

    中位数是最小堆中的最小元素或该元素与最大堆中最大元素的平均值,具体取决于大小差是 1 还是 0。

    【讨论】:

      猜你喜欢
      • 2019-04-11
      • 2020-05-08
      • 2014-05-07
      • 1970-01-01
      • 2013-12-22
      • 2015-10-06
      • 2014-11-08
      • 2021-05-27
      • 2019-10-14
      相关资源
      最近更新 更多