在O(K * log(K))中打印给定堆中最大的K元素?

时间:2012-06-26 14:25:30

标签: algorithm search tree heap big-o

鉴于以下问题,我对目前的解决方案并不完全确定:

问题:

如果有n个元素的最大堆存储在数组A中,是否可以打印K中所有最大的O(K*log(K))元素?

我的回答

是的,因为搜索元素需要O(log(K)),因此这样做

K元素的

需要O(K * log(K))个运行时间。

4 个答案:

答案 0 :(得分:15)

在大小为N的堆中搜索元素不是O(K)。首先,找到一个元素的时间复杂度取决于您尝试提取的元素数量(这是K代表的)是没有意义的。此外,没有在堆中搜索的东西 - 除非你在O(N)中计算标准的每元素搜索。

但是,找到堆中最大的元素是O(1)设计(我显然假设它是一个最大堆,所以最大元素位于堆的顶部),并从中删除最大的元素一个大小为N的堆是O(log(N))(用一个叶子元素替换它,并让那个叶子在堆中向下渗透)。

因此,从堆中提取K元素并返回未提取元素的堆,将花费O(K·log(N))时间。

如果从堆中提取K个元素非破坏性会发生什么?您可以通过保持堆堆(堆的值是其最大元素的值)来实现此目的。最初,这个堆堆只包含一个元素(原始堆)。要提取下一个最大元素,请提取顶部堆,提取其顶部元素(这是最大值),然后将两个子堆重新插入堆堆中。

每次删除时,堆积堆增加一个(删除一个,添加两个),这意味着它将永远不会超过K个元素,因此remove-one-add -two将取O(log(K))。迭代这个,你得到一个实际的O(K·log(K))算法确实返回了前K个元素,但是无法返回未提取元素的堆。

答案 1 :(得分:10)

这在max-heap中是可能的,因为您只打印树中的元素,而不是提取它们。

首先确定位于根节点的最大元素。形成指向节点的指针,并将其添加到其他空的“maximums”列表中。然后,对于每个k值,请在循环中执行以下步骤。

  • 从列表中弹出最大元素,取O(1)。
  • 打印其值,取O(1)。
  • 将此最大元素的每个子元素插入列表。插入时保持排序,取O(log(列表大小))时间。这个列表的最大大小,因为我们执行这个循环k次,是分支大小* k。因此,此步骤需要O(log(k))时间。

总的来说,根据需要,运行时间为O(klog(k))。

答案 2 :(得分:3)

实际上,它太容易了,提取max元素是O(log(N)),其中N是堆的大小。和N≠K

我将补充说,搜索随机元素是O(N)而不是O(Log(N)),但在这种情况下,我们要提取最大值。

答案 3 :(得分:3)

It is a simple and elegant algorithm to get first k elements of a max heap in k log(k) time.

steps:-

1.construct another max heap name it auxiliary heap
2.add root element of main heap to auxiliary heap
3.pop out the element from auxiliary heap and add it's 2 children to the heap
4.do step 2 and 3 till k elements have been popped out from auxiliary heap. Add the popped element's children to the auxiliary heap.