随笔 - 112  文章 - 0  评论 - 0  阅读 - 1426

数据流的中位数(优先队列)

中位数是有序整数列表中的中间值。如果列表的大小是偶数,则没有中间值,中位数是两个中间值的平均值。

  • 例如 arr = [2,3,4] 的中位数是 3 。
  • 例如 arr = [2,3] 的中位数是 (2 + 3) / 2 = 2.5 。

实现 MedianFinder 类:

  • MedianFinder() 初始化 MedianFinder 对象。

  • void addNum(int num) 将数据流中的整数 num 添加到数据结构中。

  • double findMedian() 返回到目前为止所有元素的中位数。与实际答案相差 10-5 以内的答案将被接受。

 

思路:使用两个优先队列,分别存放中位数左边的数和中位数右边的数,故需要他们分别按降序和升序排序,并且在添加元素时要注意两个队列的大小之差最多为1,这样就能直接从队头得到中位数。

复制代码
class MedianFinder {
public:
/**queMin、queMax存储 int 类型的数据,并使用 vector<int> 作为内部容器。
 *less<int> 与greater<int>是一个比较函数对象,分别实现了降序和升序排序逻辑
 */
    priority_queue<int, vector<int>, less<int>> queMin;//降序
    priority_queue<int, vector<int>, greater<int>> queMax;//升序
    MedianFinder() {
        
    }
    
    void addNum(int num) {
        if(queMin.empty()||num<=queMin.top()){
            queMin.push(num);
            //规定queMin最多只能存放比queMax的大小多1,这样当数组元素个数为奇数时,中位数就在queMin中
            if(queMin.size()>queMax.size()+1){
                queMax.push(queMin.top());
                queMin.pop();
            }
        }else{
            queMax.push(num);
            //根据规定,queMax的大小不能超过queMin的大小
            if(queMax.size()>queMin.size()){
                queMin.push(queMax.top());
                queMax.pop();
            }
        }
    }
    
    double findMedian() {
        if((queMax.size()+queMin.size())%2!=0){//根据规定,当数组元素个数为奇数时,中位数就在queMin中
            return queMin.top();
        }else{
            return (queMin.top()+queMax.top())/2.0;
        }
    }
};

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

 

posted on   _月生  阅读(9)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· AI 智能体引爆开源社区「GitHub 热点速览」
· 写一个简单的SQL生成工具
· Manus的开源复刻OpenManus初探
< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

点击右上角即可分享
微信分享提示