数据流的中位数

举报
芒果_Mango 发表于 2022/11/30 23:55:52 2022/11/30
【摘要】 295. 数据流的中位数https://leetcode.cn/problems/shu-ju-liu-zhong-de-zhong-wei-shu-lcof/295. 数据流的中位数 - 力扣(LeetCode)添加数据:保持小根堆的元素比大根堆的元素多一个,即:小根堆.size() - 大根堆.size() <=11.先添加到大根堆,此时可能不满足维持条件2.所以把大根堆的堆顶元素放到...

295. 数据流的中位数

https://leetcode.cn/problems/shu-ju-liu-zhong-de-zhong-wei-shu-lcof/

295. 数据流的中位数 - 力扣(LeetCode)

image-20220526155621983

添加数据:
保持小根堆的元素比大根堆的元素多一个,即:小根堆.size() - 大根堆.size() <=1

1.先添加到大根堆,此时可能不满足维持条件
2.所以把大根堆的堆顶元素放到小根堆中,然后大根堆的堆顶元素pop掉
3.判断大根堆和小根堆的size 如果小根堆的元素比大根堆的元素多2 -> 则需要把小根堆的堆顶放到大根堆,然后把小根堆的堆顶元素pop掉


插入的时候:
1.直接插入到大根堆,然后把大根堆的堆顶元素放到小根堆中,大根堆弹出元素 (因为要满足:小根堆的元素个数-大根堆的元素个数 = 1)

2.比较maxq.size()和minq.size()的关系
如果不满足:maxq.size()+1<minq.size(),就需要把小根堆的堆顶放到大根堆,然后小根堆弹出元素 (因为要满足:小根堆的元素个数-大根堆的元素个数 = 1)


返回中位数:
记小根堆+大根堆的元素个数为n个
如果n为奇数:返回小根堆的堆顶
如果n为偶数:返回小根堆堆顶元素+大根堆堆顶元素/2.0

image-20220526165935082

class MedianFinder {
public:
    /** initialize your data structure here. */

    //构造函数
    MedianFinder() {
    }
    priority_queue<int> maxq;//大根堆
    priority_queue<int,vector<int>,greater<int>> minq;//小根堆

    //保持小根堆的元素比大根堆的元素多一个,即:小根堆.size() - 大根堆.size() <=1
    //添加元素:
    /*
        1.先添加到大根堆,此时可能不满足维持条件
        2.所以把大根堆的堆顶元素放到小根堆中,然后大根堆的堆顶元素pop掉
        3.判断大根堆和小根堆的size 如果小根堆的元素比大根堆的元素多2 -> 则需要把小根堆的堆顶放到大根堆,然后把小根堆的堆顶元素pop掉
    */
    void addNum(int num) {
        //无脑插入大堆
        maxq.push(num);
        //插入之后可能会改变:小根堆.size() - 大根堆.size() <=1 这个条件
        //所以把大根堆的堆顶放到小根堆,然后大根堆弹出元素
        minq.push(maxq.top());
        maxq.pop();

        //如果小根堆元素比大根堆元素多两个 
        if(maxq.size() +1 < minq.size())
        {
            //把小根堆的堆顶放到大根堆
            maxq.push(minq.top());
            minq.pop();//小根堆弹出数据
        }
    }
    //查找:
    /*
        记小根堆+大根堆的元素个数为n个
        如果n为奇数:返回小根堆的堆顶
        如果n为偶数:返回小根堆堆顶元素+大根堆堆顶元素/2.0
    */
    double findMedian() {
        int size = minq.size()+maxq.size();
        //注意返回的是double类型的数据!!
        if(size & 1) //奇数
        {
            return (double)minq.top();//返回小根堆的堆顶数据
        }
        else
        {
            return (maxq.top()+minq.top())/2.0;//返回(大根堆堆顶+小根堆堆顶)/2.0
        }
    }
};

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

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。