【发布时间】:2018-04-03 07:23:08
【问题描述】:
我遇到了这个编程面试问题,但我不确定我的答案是否正确。我无法找到这个问题的正确答案。问题来了,
令 H1 和 H2 是两个(二进制)最大堆,具有 n1 和 n2 个元素 分别。如果 H1 中的每个元素都大于 H1 中的每个元素 H2,设计一种算法,将这两个堆合并为一个(二进制) O(n2) 时间内的最大堆(假设 H1 和 H2 都足够大 保存 n1 + n2 个元素)
所以,我在想,既然 H1 中的每个元素都大于 H2 中的每个元素,那么我们可以将合并的最大堆存储在 H1 中。所以,我们所要做的就是简单地从 H2 中获取第一个元素,在 H2 的数组中的位置 0 处,然后将该元素插入 H1,附加到 H1 数组的末尾,使其成为 H1 中的叶子。我们可以对 H2 中的每个元素持续执行此操作。我想一旦我们开始将 H2 中的元素作为子元素添加到 H2 的元素中,那么我们将不得不开始检查该子元素是否小于父元素,如果不是,我们交换它们。我假设由于添加一个元素,而不调用 heapify,并且在必要时进行交换会给我们带来 O(n2) 的复杂性。
那么,我的解决方案准确吗?如果没有任何帮助将不胜感激。 如果我的解决方案的任何部分不清楚,请告诉我,以便我澄清。
【问题讨论】:
-
感觉是准确的。但是我创建了一个案例,您需要进行多次交换。考虑到 H1 相对于 H2 非常小;这意味着您几乎需要对一个元素进行 log(n2) 交换(H1:[100]、H2[25 8 24 3 7 10 23 2 1 6 5 4 9 12 22])。然而,它应该是非常罕见的。如果我们能证明这种情况会非常罕见,那么你是对的:)
-
那么我的算法复杂度实际上是 O(n2 + log(n2)) 吗?我在计算复杂性方面没有太多经验,所以我不确定。那还是 O(n2) 吗?
-
老实说,我现在不确定:(
-
@selecii44:可能的错误数量随着您要合并的堆的大小(即 n2)而增加。定位要交换的节点将是一个 O(n2) 操作,并且修复它们将花费 O(log n2) 每个。解决方案是在 O(n2) 中重新排列整个 n2 堆。这使得整个操作 O(2*n2),被认为是 O(n2)。
标签: algorithm data-structures heap