[LeetCode][Java]Find Median from Data Stream
Find Median from Data Stream
Median is the middle value in an ordered integer list. If the size of the list is even, there is no middle value. So the median is the mean of the two middle value.
Examples:
[2,3,4]
, the median is 3
[2,3]
, the median is (2 + 3) / 2 = 2.5
Design a data structure that supports the following two operations:
- void addNum(int num) - Add a integer number from the data stream to the data structure.
- double findMedian() - Return the median of all elements so far.
For example:
add(1) add(2) findMedian() -> 1.5 add(3) findMedian() -> 2
https://leetcode.com/problems/find-median-from-data-stream/
找出中位数,暴力O(n^2)超时。
O(nlogn)的做法是开两个堆(java用优先队列代替)。
最小堆放小于中位数的一半,最大堆放较大的另一半。
addNum操作,把当前的num放到size小的堆中,通过2次poll-add操作,保证了最小堆中的所有数都小于最大堆中的数。
findMedian操作,如果size不同,就是其中一个堆顶,否则就是连个堆顶的数相加除以2。
1 class MedianFinder { 2 3 private Queue<Integer> max = new PriorityQueue<Integer>(Collections.reverseOrder()); 4 private Queue<Integer> min = new PriorityQueue<Integer>(); 5 6 // Adds a number into the data structure. 7 public void addNum(int num) { 8 if(max.size() < min.size()){ 9 max.add(num); 10 min.add(max.poll()); 11 max.add(min.poll()); 12 }else{ 13 min.add(num); 14 max.add(min.poll()); 15 min.add(max.poll()); 16 } 17 } 18 19 // Returns the median of current data stream 20 public double findMedian() { 21 if(max.size() < min.size()){ 22 return min.peek(); 23 }else if(max.size() > min.size()){ 24 return max.peek(); 25 }else{ 26 return (min.peek() + max.peek()) / 2.0; 27 } 28 } 29 };
上面的做法,有多余的poll-add操作,可以做些优化。
1 // Adds a number into the data structure. 2 public void addNum(int num) { 3 max.add(num); 4 min.add(max.poll()); 5 if(max.size() < min.size()){ 6 max.add(min.poll()); 7 } 8 }