如何在给定数组上构建最大堆并给出数组的索引?

时间:2013-02-21 16:54:28

标签: data-structures heap

我有以下问题:

给出一个整数数组A,并给出t 不重叠部分[L1,R1],[L2,R2] ...... [Lt,Rt]

这样每个部分都是数组(A)的起始索引(Li)和结束索引(Ri),

找到一个数据结构,该结构从O(t + klogk)复杂度返回这些部分中的顶部k元素(索引位于部分,元素位于数组A)。

非常感谢帮助者, Avihai。

2 个答案:

答案 0 :(得分:1)

问题的措辞有点模棱两可:在复杂性O(t+klogk)中要做的操作的一部分是什么?

我在回答这个问题时看到了3个选项。对于前两个,我认为是解释原始问题的错误方法,我提出答案。对于第三个也是最后一个选项,我没有解决方案。我仍然认为有必要让问题清楚,并将我的答案添加到前两个。此外,如果不是不可能的话,在评论中加入对此问题的长时间讨论会让人感到困惑。

以下是我为回答我开头的问题而看到的选项:

选项1 - 数据结构构建(使用部分)不包括

根据原始问题的当前措辞,听起来问题是要求使用数组A和部分[L1,R1],[L2,R2],...,[Lt,Rt]预先构建的数据结构以及考虑的唯一操作复杂性要求是在数据结构上完成的操作,以提取k最高值。

这并不是很有意义,因为它不清楚为什么在这种情况下t会被置于复杂性中?从您在评论中链接到的this answer到Juan的答案,您可以看到,通过仅使用相关元素预先构建堆,您可以O(klogk)获取{{1}来自数据结构的最高值元素(一旦存在)。

选项2 - 包括所有操作

如果我们读它就好像问题要求将数据结构构建为为复杂性要求考虑的操作的一部分(我们只获取数组和索引列表k并且必须使用那么复杂性要求无法实现。如果要构建数据结构,至少需要遍历需要插入数据结构的所有元素,如果您不想构建数据结构并且打算使用数组因为它是你必须遍历你需要找到最大值之间的所有元素。无论哪种方式,如果你得到[L1,R1,L2,R2,...,Lt,Rt]t=1,其中L1=1, R1=n是数组n中元素的数量,你将必须遍历A中的所有元素(您对A的元素'顺序没有任何假设)。这意味着您至少需要A,且要求为O(n)。为了更清楚地表明这些是完全不相关的数量 - 您可以考虑O(t+klogk)的情况,意味着只找到最高元素,而k=1可以是任意长度(让我们说10,000 )。

选项3 - 仅使用数组免除

构建数据结构

这让我想到了问题背后的原始含义:事先从给定数组A构建数据结构(其构建将不包含在复杂性要求中),以便稍后你得到的部分'您之前构建的数据结构的索引A和整数[L1,R1],[L2,R2],...[Lt,Rt]将允许您获取新给定索引(k)定义的部分中的k最高元素复杂L1,R1,L2,R2,...,Lt,Rt中的原始数组A。 不幸的是,我还没有找到解决这个问题的方法 - 或者证明这样的解决方案不存在,但至少现在问题是有道理的。

我很想知道哪个选项是问题的初衷,如果我想出选项3的解决方案,我会相应地编辑这个答案。

答案 1 :(得分:0)

我构建了一个间接表T,它将[0..t]映射到各部分映射的索引。

然后我使用这个间接表运行heapify算法。每次算法访问A [i]时,它都会被A [T [i]]替换。

间接表构造和堆化都是O(t)。获得前k个元素将花费O(t log n)。

编辑: Wikipedia explains在其文章中如何在O(t)中构建堆。

基本上它是一系列泡沫破灭操作:

for i from floor(A.size()/2) to 0:
    bubble_down(A, i)

文章中有一个证明为什么这是O(t)。