思路
step1:当max-heap(存的是左半边元素,较小者)为空或者待加入元素小于等于max-heap顶元素,则加入max-heap;否则加入min-heap(存的较大元素,右半边元素)。step2: 如果经过step1后,maxheap的size比min-heap的size大超过1,那么就把maxheap的堆顶元素给min-heap;反之亦反。
求中位数:两个pq的size之和为偶数则加入返回两个pq的堆顶元素的均值;为奇数则返回两个pq中size大的那个的堆顶元素。
代码
class MedianFinder {
PriorityQueue<Integer> maxHeap, minHeap;
/** initialize your data structure here. */
public MedianFinder() {
Comparator<Integer> rev = new Comparator<Integer>() {
@Override
public int compare(Integer i1, Integer i2) {
return i2 - i1;
}
};
minHeap = new PriorityQueue<>();
maxHeap = new PriorityQueue<>(rev);
}
public void addNum(int num) {
if(maxHeap.isEmpty() || num <= maxHeap.peek())
maxHeap.offer(num);
else
minHeap.offer(num);
if(maxHeap.size() - minHeap.size() > 1) {
minHeap.offer(maxHeap.poll());
}
else if(minHeap.size() - maxHeap.size() > 1) {
maxHeap.offer(minHeap.poll());
}
}
public double findMedian() {
int size = maxHeap.size() + minHeap.size();
double result = 0;
if(size % 2 == 0) {
result = (maxHeap.peek() + minHeap.peek()) * 1.0 / 2;
}
else {
result = (maxHeap.size() > minHeap.size()) ?
maxHeap.peek() : minHeap.peek();
}
return result;
}
}
/**
* Your MedianFinder object will be instantiated and called as such:
* MedianFinder obj = new MedianFinder();
* obj.addNum(num);
* double param_2 = obj.findMedian();
*/
复杂度分析
时间复杂度:add为O(logn), findMedian为O(1)
空间复杂度: O(n)