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
进阶:
- 如果数据流中所有整数都在 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 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 }