题解34 | #升序小堆#降序大堆#数据流中的中位数#

数据流中的中位数

https://www.nowcoder.com/practice/9be0172896bd43948f8a32fb954e1be1

#include <functional>
#include <queue>
class Solution {
private:
    priority_queue<int,vector<int>,less<int>> max; //大顶堆
    priority_queue<int,vector<int>,greater<int>> min; //小顶堆
    //此处容易出错,大顶堆是降序,应选less,小顶堆是升序,选greater
public:
    void Insert(int num) {
        if(max.empty() || num <= max.top()){//判断条件必须先判空
            max.push(num);
        }
        else {
            min.push(num);
        }

        int li = min.size();
        int la = max.size();
        //大堆里边多了的话
        if( la - li > 1){
            int top = max.top();
            min.push(top);
            max.pop();
        }
        //小堆里边多了的话
        else if(li - la > 1){
            int top = min.top();
            max.push(top);
            min.pop();
        }
       
    }

    double GetMedian() { 
        int li = min.size();
        int la = max.size();
        double mid;

        if(li > la){
            mid = min.top();
            return mid;
        }
        else if (la > li) {
            mid = max.top();
            return mid;
        }
        else {
            mid = double(max.top()+min.top())/2;
            return mid;
        }
    }

};

算法基本思想:

该算法使用两个堆来实现动态获取中位数的功能。

一个是大顶堆,存放较小的一半数;另一个是小顶堆,存放较大的一半数。

插入操作时,先将数插入到大顶堆中,再将大顶堆的堆顶元素插入到小顶堆中。保持两个堆的大小差不超过1。

1.获取中位数时,如果两个堆的大小相等,则取两个堆顶元素的平均值作为中位数;

2.如果大顶堆的大小比小顶堆大1,则中位数为大顶堆的堆顶元素;

3.如果小顶堆的大小比大顶堆大1,则中位数为小顶堆的堆顶元素。

时间复杂度:

插入操作的时间复杂度为O(log n),获取中位数的时间复杂度为O(1)。

空间复杂度:

空间复杂度为O(n),其中n为插入的元素个数。

头文件以及private部分的解释:

#include <functional>:引入了函数对象的头文件,用于定义堆的比较函数。

private部分:

priority_queue<int,vector<int>,less<int>> max;:定义了一个大顶堆,用于存放较小的一半数。

priority_queue<int,vector<int>,greater<int>> min;:定义了一个小顶堆,用于存放较大的一半数。

2024考研数据结构 文章被收录于专栏

本人考研刷算法题,立此专栏练习强化。

全部评论

相关推荐

点赞 收藏 评论
分享
牛客网
牛客企业服务