【64】295. Find Median from Data Stream

295. Find Median from Data Stream

Description Submission Solutions Add to List

  • Total Accepted: 34534
  • Total Submissions: 145013
  • Difficulty: Hard
  • Contributors: Admin

 

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

Solution:

用两个堆(从大到小排序),小堆存前半段,大堆存后半段(存负数来实现从小到大排序)。如果小堆的size大于大堆,则取小堆的top为中位数;若size相同,则取两个堆的top的平均值。

1. 用priority_queue实现

class MedianFinder {
public:
    /** initialize your data structure here. */
    MedianFinder() {
        
    }
    
    void addNum(int num) {
        small.push(num);
        large.push(-small.top());
        small.pop();
        if(small.size() < large.size()){
            small.push(-large.top());
            large.pop();
        }
    }
    
    double findMedian() {
        return (small.size() > large.size()) ? (double)small.top() : (double)(small.top() - large.top())/2;
    }
private:
    priority_queue<int> large, small;
};

/**
 * Your MedianFinder object will be instantiated and called as such:
 * MedianFinder obj = new MedianFinder();
 * obj.addNum(num);
 * double param_2 = obj.findMedian();
 */

2. 用multiset实现

class MedianFinder {
public:
    /** initialize your data structure here. */
    MedianFinder() {
        
    }
    
    void addNum(int num) {
        small.insert(num);
        large.insert(-*small.begin());
        small.erase(small.begin());
        if (small.size() < large.size()) {
            small.insert(-*large.begin());//begin()是指针,用*来取值
            large.erase(large.begin());
        }
    }

    // Returns the median of current data stream
    double findMedian() {
        return small.size() > large.size() ? *small.begin() : 0.5 * (*small.begin() - *large.begin());//
    }

private:
    multiset<long> small, large;//insert(), begin(), erase()
};

/**
 * Your MedianFinder object will be instantiated and called as such:
 * MedianFinder obj = new MedianFinder();
 * obj.addNum(num);
 * double param_2 = obj.findMedian();
 */

 

 
 
 
 
posted @ 2017-02-12 17:26  会咬人的兔子  阅读(126)  评论(0编辑  收藏  举报