/** 如何獲得一個數據流中的中位數? 若是從數據流中讀出奇數個數值,那麼中位數就是全部數值排序以後位於中間的數值。 若是從數據流中讀出偶數個數值,那麼中位數就是全部數值排序以後中間兩個數的平均值。 咱們使用 Insert()方法讀取數據流,使用 GetMedian()方法獲取當前讀取數據的中位數。 */
/** 最大堆和最小堆 * 每次插入小頂堆的是當前大頂堆中最大的數 * 每次插入大頂堆的是當前小頂堆中最小的數 * 這樣保證小頂堆中的數永遠大於等於大頂堆中的數(值) * 中位數就能夠方便地從二者的根結點中獲取了 * 奇數的話 小根堆中的元素數 大於 大根堆中的元素數(數量) */
import java.util.PriorityQueue; import java.util.Comparator; public class Solution { //小頂堆 private PriorityQueue<Integer> minHeap = new PriorityQueue<Integer>(); //大頂堆 private PriorityQueue<Integer> maxHeap = new PriorityQueue<Integer>(new Comparator<Integer>() { @Override public int compare(Integer o1, Integer o2) { return o2 - o1; } }); //記錄元素個數偶數個仍是奇數個 int count = 0; 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(minHeap.peek() + maxHeap.peek())/2; }else{ /**當前爲奇數個,則直接從小頂堆中取元素便可*/ return new Double(minHeap.peek()); } } }