63. 數據流的中位數

題目描述

如何得到一個數據流中的中位數?如果從數據流中讀出奇數個數值,那麼中位數就是所有數值排序之後位於中間的數值。如果從數據流中讀出偶數個數值,那麼中位數就是所有數值排序之後中間兩個數的平均值。我們使用Insert()方法讀取數據流,使用GetMedian()方法獲取當前讀取數據的中位數

Solution

使用一個小頂堆和一個大頂堆存儲數據,小頂堆所有的數都大於大頂堆,插入數據時保持兩個堆大小相差不超過1,這樣中位數會在小頂堆和大頂堆的堆頂產生

  1. 當前數據量爲偶數時,插入新數據時,要讓小頂堆大小加1,將新數據插入大頂堆中,將大頂堆堆頂移入小頂堆(按序插入新數據)
  2. 當前數據量爲奇數時,插入新數據時,要讓大頂堆大小加1,保持兩個堆大小相差不超過1,將新數據插入小頂堆中,將小頂堆堆頂移入大頂堆(按序插入新數據)
  3. 當前數據量爲偶數時,中位數爲兩個堆頂的平均值;當前數據量爲奇數時,中位數爲小頂堆堆頂
public class Solution {
		private int count = 0;
		private PriorityQueue<Integer> minHeap = new PriorityQueue<>();
		private PriorityQueue<Integer> maxHeap = new PriorityQueue<Integer>(new Comparator<Integer>() {
			@Override
			public int compare(Integer o1, Integer o2) {
				return o2 - o1;
			}
		});
	
	    public void Insert(Integer num) {
	    	if (count % 2 == 0) {
	    		maxHeap.offer(num);
	    		int max = maxHeap.poll();
	    		minHeap.offer(max);
	    	} else {
	    		minHeap.offer(num);
	    		int min = minHeap.poll();
	    		maxHeap.offer(min);
	    	}
	        count++;
	    }

	    public Double GetMedian() {
	        if (count % 2 == 0) {
	        	return new Double(maxHeap.peek() + minHeap.peek()) / 2;
	        } else {
	        	return new Double(minHeap.peek());
	        }
	    }
	}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章