这是一个面试问题。设计一个类,它存储整数并提供两个操作:
void insert(int k) int getMedian()
我想我可以使用BST以便insert
取O(logN)而getMedian
取O(logN)(对于getMedian
我应该添加左/右孩子的数量对于每个节点)。
现在我想知道这是否是最有效的解决方案,没有更好的解决方案。
答案 0 :(得分:23)
您可以使用2个堆,我们会调用Left
和Right
Left
是Max-Heap
Right
是Min-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)更好。
另外,通过更灵活一点,您可以根据输入的属性更改排序算法来提高性能(输入几乎是否排序......)。
我在计算机科学中非常自学,但这就是我的方式:更简单更好。