LeetCode 295. Find Median from Data Stream

原题链接在这里:https://leetcode.com/problems/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:

addNum(1)
addNum(2)
findMedian() -> 1.5
addNum(3) 
findMedian() -> 2

题解:

维护两个堆,一个maxHeap用来存较小的一半数,一个minHeap用来存较大的一半数。每次添加时看minHeap的root是不是小于 num, 若是就把num加在minHeap上,若不然就看看maxHeap的root是不是大于num, 若是就把num加在maxHeap上面.

不是上面两种情况默认加载minHeap里.

加完后需要balance 两个heap的大小,默认maxHeap的size不比minHeap的size大, 因为默认添加到minHeap中. 但minHeap也不能超过maxHeap的size大过1.

findMedian  若是size相同,一边取一个算平均数, 否则从minHeap中poll出结果.

Time Complexity: AddNum(), O(logn), n = minHeap.size(). findMedian(), O(1).

Space: O(n). 两个heap大小.

AC Java:

 1 class MedianFinder {
 2     
 3     PriorityQueue<Integer> minHeap;
 4     PriorityQueue<Integer> maxHeap;
 5     /** initialize your data structure here. */
 6     public MedianFinder() {
 7         minHeap = new PriorityQueue<Integer>();
 8         maxHeap = new PriorityQueue<Integer>(Collections.reverseOrder());
 9     }
10     
11     public void addNum(int num) {
12         if(!maxHeap.isEmpty() && maxHeap.peek()>num){
13             maxHeap.add(num);
14         }else{
15             minHeap.add(num);
16         }
17         
18         if(maxHeap.size() > minHeap.size()){
19             minHeap.add(maxHeap.poll());
20         }else if(minHeap.size() - maxHeap.size() > 1){
21             maxHeap.add(minHeap.poll());
22         }
23     }
24     
25     public double findMedian() {
26         if(minHeap.size() == maxHeap.size()){
27             return ((double)minHeap.peek() + (double)maxHeap.peek()) / 2.0;
28         }else{
29             return (double)minHeap.peek();
30         }
31     }
32 }
33 
34 /**
35  * Your MedianFinder object will be instantiated and called as such:
36  * MedianFinder obj = new MedianFinder();
37  * obj.addNum(num);
38  * double param_2 = obj.findMedian();
39  */

Could also write like this for addNum.

 1 class MedianFinder {
 2     PriorityQueue<Integer> minHeap;
 3     PriorityQueue<Integer> maxHeap;
 4 
 5     public MedianFinder() {
 6         minHeap = new PriorityQueue<>();
 7         maxHeap = new PriorityQueue<>(Collections.reverseOrder());    
 8     }
 9     
10     public void addNum(int num) {
11         minHeap.add(num);
12         maxHeap.add(minHeap.poll());
13         if(maxHeap.size() > minHeap.size()){
14             minHeap.add(maxHeap.poll());
15         }
16     }
17     
18     public double findMedian() {
19         return maxHeap.size() == minHeap.size() ? (maxHeap.peek() + minHeap.peek()) / 2.0 : minHeap.peek();
20     }
21 }
22 
23 /**
24  * Your MedianFinder object will be instantiated and called as such:
25  * MedianFinder obj = new MedianFinder();
26  * obj.addNum(num);
27  * double param_2 = obj.findMedian();
28  */

类似Sliding Window Median.

posted @ 2015-11-04 07:17  Dylan_Java_NYC  阅读(493)  评论(0编辑  收藏  举报