我正在努力想出解决以下问题的方法:
给定一个用数组表示的最大堆,返回第k大的元素而不修改堆。我被要求在线性时间内完成,但被告知可以在对数时间内完成。
我想到了一种解决方案:
使用第二个最大堆并将k或k+1个值填充进去(广度优先遍历原始堆),然后弹出k个元素并获取所需元素。我认为这应该是O(N+logN)=O(N)。
是否有更好的解决方案,也许是O(logN)时间?
我正在努力想出解决以下问题的方法:
给定一个用数组表示的最大堆,返回第k大的元素而不修改堆。我被要求在线性时间内完成,但被告知可以在对数时间内完成。
我想到了一种解决方案:
使用第二个最大堆并将k或k+1个值填充进去(广度优先遍历原始堆),然后弹出k个元素并获取所需元素。我认为这应该是O(N+logN)=O(N)。
是否有更好的解决方案,也许是O(logN)时间?
Input:
Integer kth <- 8
Heap heap <- {19,18,10,17,14,9,4,16,15,13,12}
BEGIN
Heap positionHeap <- Heap with comparation: ((n0,n1)->compare(heap[n1], heap[n0]))
Integer childPosition
Integer candidatePosition <- 0
Integer count <- 0
positionHeap.push(candidate)
WHILE (count < kth) DO
candidatePosition <- positionHeap.pop();
childPosition <- candidatePosition * 2 + 1
IF (childPosition < size(heap)) THEN
positionHeap.push(childPosition)
childPosition <- childPosition + 1
IF (childPosition < size(heap)) THEN
positionHeap.push(childPosition)
END-IF
END-IF
count <- count + 1
END-WHILE
print heap[candidate]
END-BEGIN
我在这里找到了弗雷德里克森(Frederickson)撰写的“最小堆中选择的最优算法”: ftp://paranoidbits.com/ebooks/An%20Optimal%20Algorithm%20for%20Selection%20in%20a%20Min-Heap.pdf
EDITED
没有O(log n)时间复杂度的算法,这是因为基于简单的细胞探针下界。假设k是2的幂次方(不失一般性),堆看起来像(最小堆入队,因为容易标记,但实际上没有实质区别)。
1
2 3
4 5 6 7
.............
permutation of [k, 2k).
数组中的最大堆:i
为基于0的索引,i
处的元素大于2*i+1
和2*i+2
处的元素。
您需要另一个最大堆(insert
、pop
、empty
),其中包含按value
排序的元素对(value, index)
。伪代码(不包括边界检查):
input: k
1. insert (at(0), 0)
2. (v, i) <- pop and k <- k - 1
3. if k == 0 return v
4. insert (at(2*i+1), 2*i+1) and insert (at(2*+2), 2*+2)
5. goto 2
运行时评估