数据流的中位数

数据流的中位数_第1张图片

动态维护一个最大堆和一个最小堆,最大堆存储一半数据,最小堆存储一半数据,维持最大堆的堆顶比最小堆的堆顶小

偶数个数时,中位数就是两个堆顶的一半。奇数个数时,就是某一个堆顶。

添加元素时堆顶的调整:

1.最大堆与最小堆元素个数相同时:来一个数,这个数比最大堆堆顶小的话,添加进最大堆。这个数比最小堆堆顶大的话,push进最小堆

2.最大堆比最小堆多一个元素时:这个数比最大堆堆顶小的话,将最大堆堆顶push进最小堆,并在最大堆中弹出它,然后把新来的这个数push到最大堆。这个数比最大堆堆顶大的话,直接push到最小堆

3.最大堆比最小堆少一个元素时:刚好相反。如果来的这个数比最小堆堆顶大的话,将最小堆堆顶push到最大堆,然后在最小堆pop,将新来的数再添加到最小堆。如果新的这个数比最小堆堆顶小的话,Push到最大堆


class MedianFinder {
public:
    /** initialize your data structure here. */
    priority_queue big_heap;
    priority_queue,greater > small_heap;
    
    MedianFinder() {       
    }
    
    void addNum(int num) {
        if(big_heap.empty())
        {
            big_heap.push(num);
            return;
        }
        
        if(big_heap.size() == small_heap.size())//
        {
            if(num small_heap.size())//
        {
            if(num > big_heap.top())
            {
                small_heap.push(num);
            }else
            {
                small_heap.push(big_heap.top());
                big_heap.pop();
                big_heap.push(num);
            }
                
        }
        else if(big_heap.size() < small_heap.size())//
        {
            if(num < small_heap.top())
                big_heap.push(num);
            else
            {
                big_heap.push(small_heap.top());
                small_heap.pop();
                small_heap.push(num);
            }
        }
        
    }
    
    double findMedian() {
        if(big_heap.size() == small_heap.size())
            return 1.0*(big_heap.top() + small_heap.top())/2;//注意乘以1.0,这个错误我找了很久,麻蛋
        else if(big_heap.size() > small_heap.size())
            return big_heap.top();
        
            return small_heap.top();
    }
    

};

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

你可能感兴趣的:(LeetCode)