用一个最大堆,一个最小堆分别维护排序后的数据流的左右两部分,插入时如果两个堆中元素数量一样,那么我们规定始终往最大堆中添加元素(最小堆也行),但添加前我们要把该元素加入最小堆中,再从最小堆中取出堆顶元素加入最大堆中。插入时如果最大堆多一,就以相同的方法把元素加入到最小堆中
主要分析一下这种方法与单纯维护一个列表来说有什么优势
取中位数都是一样的O(1)
插入元素,在列表中需要O(logn)(列表是有序的)来寻找插入的下标,再O(n)来插入元素。而对于堆来说只需要O(logn)即可完成插入元素
ps:第一次困难题秒解,思路还和题解一样
class MedianFinder {
Queue<Integer> q1, q2;
/** initialize your data structure here. */
public MedianFinder() {
q1 = new PriorityQueue<>((o1,o2) -> o1 - o2);
q2 = new PriorityQueue<>((o1,o2) -> o2 - o1);
}
public void addNum(int num) {
if(q1.size() == q2.size()){
q2.add(num);
q1.add(q2.poll());
}else{
q1.add(num);
q2.add(q1.poll());
}
}
public double findMedian() {
if(q1.size() == q2.size()){
return ((double)q1.peek() + q2.peek()) / 2;
}else{
return (double)q1.peek();
}
}
}