思路:极大堆、极小堆。因为输入是数据流不是数组,说明输入的数据是不确定的。一般来说先排序,然后返回中间数,但每查询一次就要排序,时间复杂度较高。所以想能不能每次查询都可以直接获取到中间数,而不是对输入的数据排序取中间数。那么,我们就把输入的数据分为两堆,每次输入数据都只会进入两个堆中的一个,而两个堆的中间分界线就是中位数。
代码:
class MedianFinder { PriorityQueue<Integer> maxHeap, minHeap; /** initialize your data structure here. */ public MedianFinder() { maxHeap = new PriorityQueue<>((a, b) -> b - a); minHeap = new PriorityQueue<>((a, b) -> a - b); } public void addNum(int num) { if(maxHeap.isEmpty()){ maxHeap.offer(num); return ; } if(num <= maxHeap.peek()){ maxHeap.offer(num); }else{ minHeap.offer(num); } this.adjust(); } public double findMedian() { return maxHeap.size()==minHeap.size()?(double)(maxHeap.peek()+minHeap.peek())/2:maxHeap.size() > minHeap.size()?maxHeap.peek():minHeap.peek(); } private void adjust(){ if(maxHeap.size() - minHeap.size() < 2 && maxHeap.size() - minHeap.size() > -2){ return ; } if(maxHeap.size() - minHeap.size() >= 2){ minHeap.offer(maxHeap.poll()); } if(maxHeap.size() - minHeap.size() <= -2){ maxHeap.offer(minHeap.poll()); } } } /** * Your MedianFinder object will be instantiated and called as such: * MedianFinder obj = new MedianFinder(); * obj.addNum(num); * double param_2 = obj.findMedian(); */
执行用时:75 ms, 在所有 Java 提交中击败了92.29%的用户
内存消耗:49.8 MB, 在所有 Java 提交中击败了40.09%的用户