LeetCode295. 数据流的中位数(C++)

题目描述

中位数是有序列表中间的数。如果列表长度是偶数,中位数则是中间两个数的平均值。

例如,

[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

解题思路:动态维护一个最大堆和一个最小堆,最大堆存储一半元素最小堆存储一半元素,维持最大堆的堆顶比最小堆的堆顶小。

1.当最大堆与最小堆元素个数相同时,新元素小于最大堆,就push进最大堆,反之则入最小堆。

2.当最大堆比最小堆多一个元素:

(1)如果新元素小于最大堆堆顶:经最大堆的堆顶push进入最小堆,将最大堆的堆顶移除,将新元素添加到最大堆。

(2)如果新元素大与最大堆堆顶,竟新元素直接push到最小堆。

3.当最大堆比最小堆少一个元素:

(1)如果新元素小于最小堆的堆顶,将新元素直接push进入最大堆。

(2)如果新元素大与最小堆堆顶,将最小堆的堆顶push进入最大堆,将最小堆的堆顶一出,将新元素添加至最小堆。

4.最后获取中位数。

(1)最大堆最小堆中的元素个数相同时,中位数是最大堆堆顶与最小堆堆顶的平均值。

(2)最大堆比最小堆多一个元素时,中位数是最大堆的堆顶。

(3)最大堆比最小堆少一个元素,中位数是最小堆堆顶。

下面是我的代码,因为思路写的已经很全所以么有些注释,其实就是按照思路一步一步走就可以了。

class MedianFinder {
public:
    /** initialize your data structure here. */
    MedianFinder() {
        
    }
    
    void addNum(int num) {
        if(big_heap.empty()){
            big_heap.push(num);
            return;
        }
        if(big_heap.size()==small_heap.size()){
            if(num>big_heap.top()){
                small_heap.push(num);
            }else{
                big_heap.push(num);
            }
        }else if(big_heap.size()>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 (big_heap.top()+small_heap.top())/2.0;
            
        }else if(big_heap.size()>small_heap.size()){
            return big_heap.top();
        }else{
            return small_heap.top();
        }
        
    }
    private:
    priority_queue<int ,vector<int >,less<int>> big_heap;
    priority_queue<int ,vector<int >,greater<int>> small_heap;
};

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

猜你喜欢

转载自blog.csdn.net/a15929748502/article/details/89361760
今日推荐