使用数据结构自平衡二分查找树查找数组中第n个最小/最大元素的算法..
阅读帖子:Find kth smallest element in a binary search tree in Optimum way。但正确的答案并不清楚,因为我无法弄清楚正确的答案,我拿了一个例子......请多说明一点......
答案 0 :(得分:13)
C.A.R。 Hoare的select
算法就是为了这个目的而设计的。它在[预期]线性时间内执行,具有对数额外存储。
编辑:排序的明显替代方案,然后选择正确的元素具有O(N log N)复杂度而不是O(N)。以排序顺序存储i
个最大元素需要O(i)辅助存储,并且大致为O(N * i log i)复杂度。如果i
已知先验非常小(例如1或2),则此可以获胜。对于更一般的用途,select
通常更好。
Edit2:offhand,我没有很好的参考,但在previous answer中描述了这个想法。
答案 1 :(得分:2)
首先对数组进行降序排序,然后取i
个元素。
答案 2 :(得分:0)
创建一个排序数据结构来保存i
个元素,并将初始计数设置为0。
处理源数组中的每个元素,将其添加到该新结构,直到新结构已满。
然后处理源数组的其余部分。对于每个大于排序数据结构中最小值的结构,从该结构中删除最小值并将新结构放入。
处理完源数组中的所有元素后,您的结构将保留i
个最大元素。只需抓住最后一个,你就拥有了i
'最伟大的元素。
瞧!
或者,对其进行排序,然后直接抓取i
'元素。
答案 3 :(得分:0)
对于具有非常低插入和低delete_min成本的堆来说,这是一个合适的任务。例如。 pairing heaps。它将具有最坏的情况O(n * log(n))性能。但是,由于实现起来非常重要,最好先在别处selection algorithms进行检查。
答案 4 :(得分:0)
您的任务有多种策略可供选择(如果您不首先关注自平衡树)。
通常是权衡速度/记忆。大多数算法都需要修改阵列或O(N)
额外存储。
具有自平衡树的解决方案属于后一类,但这不是正确的选择。问题是构建树本身需要O(N*log N)
,这将主导后面的搜索术语,最终复杂度为O(N*log N)
。因此,您不仅仅是简单地对数组进行排序并使用复杂的数据结构......
一般来说,问题在很大程度上取决于与i
相关的N
的大小。如果你想一分钟,对于i == 1
它是微不足道的吗?它被称为找到最大值。
嗯,同样的策略显然适用于线性时间内i == 2
(携带2个最大元素)。而且它也是平凡对称的:即如果你需要找到第N-1个元素,那么只需携带2个最小元素。
然而,当i
约为N / 2或N / 4时,它会失去效率。携带i个最大元素则意味着对大小为i
的数组进行排序...因此我们会回到N*log N
墙上。
Jerry Coffin指出了一个简单的解决方案,适用于这种情况。以下是Wikipedia的参考资料。完整的文章还描述了中位数中位数方法:它更可靠,但涉及更多工作,因此通常较慢。
答案 5 :(得分:0)
Create an empty list L
For each element x in the original list,
add x in sorted position to L
if L has more than i elements,
pop the smallest one off L
if List2 has i elements,
return the i-th element,
else
return failure
这应该取O(N(log(i)))。如果假设i是常数,则它是O(N)。
答案 6 :(得分:0)
从元素构建堆并调用MIN
i
次。