1. 程式人生 > >Leetcode 295.資料流的中位數

Leetcode 295.資料流的中位數

資料流的中位數

中位數是有序列表中間的數。如果列表長度是偶數,中位數則是中間兩個數的平均值。

例如,

[2,3,4] 的中位數是 3

[2,3] 的中位數是 (2 + 3) / 2 = 2.5

設計一個支援以下兩種操作的資料結構:

  • void addNum(int num) - 從資料流中新增一個整數到資料結構中。
  • double findMedian() - 返回目前所有元素的中位數。

示例:

addNum(1)

addNum(2)

findMedian() -> 1.5

addNum(3)

findMedian() -> 2

進階:

  1. 如果資料流中所有整數都在 0 100 範圍內,你將如何優化你的演算法?
  2. 如果資料流中 99% 的整數都在 0 100 範圍內,你將如何優化你的演算法?

 

建立2個堆,一個是最小堆,一個是最大堆

 

 1 import java.util.Comparator;
 2 import java.util.PriorityQueue;
 3 
 4 
 5 //方法類似與480題的sliding window median
 6  /*
 7      Use two Heaps to store numbers. maxHeap for numbers smaller than current
8 * median, minHeap for numbers bigger than and equal to current median. A 9 * small trick I used is always make size of minHeap equal (when there are 10 * even numbers) or 1 element more (when there are odd numbers) than the 11 * size of maxHeap 12 */ 13 public class MedianFinder {
14 15 PriorityQueue<Integer> minHeap;//使minHeap中的個數等於或者比maxHeap多1,這樣對於返回中位數操作就相對簡單 16 PriorityQueue<Integer> maxHeap; 17 18 public MedianFinder() { 19 this.minHeap = new PriorityQueue<>(); 20 this.maxHeap = new PriorityQueue<>(new Comparator<Integer>() { 21 public int compare(Integer o1, Integer o2) { 22 return o2.compareTo(o1); 23 } 24 }); 25 } 26 27 public void addNum(int num) { 28 if (num < findMedian()) 29 maxHeap.add(num); 30 else 31 minHeap.add(num); 32 if (maxHeap.size() > minHeap.size()) 33 minHeap.add(maxHeap.poll()); 34 if (minHeap.size() - maxHeap.size() > 1) 35 maxHeap.add(minHeap.poll()); 36 } 37 38 public double findMedian() { 39 if (minHeap.isEmpty() && maxHeap.isEmpty()) 40 return 0; 41 if (minHeap.size() == maxHeap.size()) 42 return ((double) minHeap.peek() + (double) maxHeap.peek()) / 2.0; 43 else 44 return (double) minHeap.peek(); 45 } 46 }