Leetcode 295.資料流的中位數
阿新 • • 發佈:2019-01-01
資料流的中位數
中位數是有序列表中間的數。如果列表長度是偶數,中位數則是中間兩個數的平均值。
例如,
[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
進階:
- 如果資料流中所有整數都在 0 到 100 範圍內,你將如何優化你的演算法?
- 如果資料流中 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 current8 * 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 }