数据结构找到中位数

时间:2012-07-06 11:27:26

标签: data-structures language-agnostic selection

这是一个面试问题。设计一个类,它存储整数并提供两个操作:

void insert(int k)
int getMedian()

我想我可以使用BST以便insert取O(logN)而getMedian取O(logN)(对于getMedian我应该添加左/右孩子的数量对于每个节点)。

现在我想知道这是否是有效的解决方案,没有更好的解决方案。

4 个答案:

答案 0 :(得分:23)

您可以使用2个堆,我们会调用LeftRight LeftMax-Heap RightMin-Heap 插入如下:

  • 如果新元素x小于Left的根,则我们会将x插入Left
  • 否则,我们会将x插入Right
  • 如果在Left插入后Right的元素数量大于1 Left的元素数,则我们会在Right上调用Extract-Max并将其插入{{ 1}}。
  • 否则,如果插入Right后的元素数量大于Left元素数,则我们会在Right上调用Extract-Min并将其插入{{1 }}。

中位数始终是Left的根。

因此,在Left时间内完成插入,并在O(lg n)时间内完成中位数。

答案 1 :(得分:3)

请参阅this Stack Overflow问题,了解涉及两个堆的解决方案。

答案 2 :(得分:2)

您也可以考虑使用自平衡树。如果树是完全平衡的,那么根节点就是你的中位数。比方说,树的一端更深一层。然后,您只需要知道在更深的一侧有多少节点来选择正确的中位数。

答案 3 :(得分:1)

如果你在O<中选择你的候选人,它会击败一个整数数组,它会在插入时用一个专用于整数的排序算法(http://en.wikipedia.org/wiki/Sorting_algorithm)进行排序。 O(log(n))并使用数组,然后getMedian将索引的大小的一半将是O(1),不是吗?我似乎可以做得比log(n)+ log(n)更好。

另外,通过更灵活一点,您可以根据输入的属性更改排序算法来提高性能(输入几乎是否排序......)。

我在计算机科学中非常自学,但这就是我的方式:更简单更好。