首页 > 其他分享 >剑指 Offer 41. 数据流中的中位数

剑指 Offer 41. 数据流中的中位数

时间:2023-09-13 22:24:25浏览次数:29  
标签:大根堆 Offer up 中位数 down num 41 size

class MedianFinder {
public:
    /** initialize your data structure here. */
    // 注意小根堆的定义方式
    priority_queue<int, vector<int>, greater<int>> up; // 小根堆,默认放从大到小后一半的数
    priority_queue<int> down; // 大根堆,默认放从小到大排序前一半的数
    // 注意:大根堆的堆顶小于小根堆的堆顶,两个数是大小是紧挨着的,两个队呈现两个三角对顶的关系
    MedianFinder() {

    }
    
    void addNum(int num) {
        // 如果下面是空的,或者num小于大根堆堆顶元素
        // 这里一定要注意加上小根堆为空的条件,否则当判断num <= down.top()时,由于down中不存在数据,会越界访问
        if(down.empty() || num <= down.top()) {
            // 将num查到大根堆
            down.push(num);

            // 当插入一个新数后,大根堆比小根堆多两个数,此时大根堆需要将堆顶pop掉作为小根堆的堆顶
            if(down.size() > up.size() + 1) {
                up.push(down.top());
                down.pop();
            } 
        } 
        else {
            // 如果num大于大根堆堆顶,并且小根堆不为空
            up.push(num);
            // 如果大根堆比小根堆的数多了,那么将小根堆的堆顶pop掉作为大根堆的堆顶
            if(down.size() < up.size()) {
                down.push(up.top());
                up.pop();
            }
        }
    }
    
    double findMedian() {
        // 这时要比较两个堆存数的个数。正常情况下两种情况:
        // 第一种,大根堆比小根堆多一个数,那么中位数就是大根堆的堆顶
        // 第二种,大根堆和小根堆存数的数量相等,那么中位数就是大根堆和小根堆的均值
        // 因此,每新插入一个数,都要维护大小根堆的size的动态平衡。

        // 如果两个堆的数据个数相加为奇数,说明大根堆比小根堆多一个数,中位数是大根堆堆顶
        if((down.size() + up.size()) % 2) return down.top();

        // 如果数据个数相等,中位数就是两者堆顶的平均数
        // 注意,除以2.0,否则结果会下取整,变为整形
        else return (down.top() + up.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();
 */

 

标签:大根堆,Offer,up,中位数,down,num,41,size
From: https://www.cnblogs.com/luxiayuai/p/17700942.html

相关文章

  • 爆肝总结2023Android面试,看完学会它,公司追着给你offer
    前言想要在面试中脱颖而出吗?想要在最短的时间内快速掌握Android的核心知识点吗?想要成为一位优秀的Android工程师吗?本篇文章能助你一臂之力!金九银十,目前正值招聘求职旺季,很多朋友对一些新技术名词都能侃侃而谈,但对一些核心原理理解的不够透彻,特别是对Android的一些核心基础知识点掌......
  • 【题解】Educational Codeforces Round 141(CF1783)
    评价:educationalA.MakeitBeautiful题目描述:如果一个数组中存在一个数恰好等于该数前面所有数之和,那么这个数组就是丑的。如果一个数组不是丑的,就是美的。比如说:数组$[6,3,9,6]$是丑的,因为\(9=6+3\);数组$[5,5,7]$是丑的,因为第二个\(5=5\)。数组$......
  • CF441C
    一道超级水的思维题,又是exlg跳题跳到的,建议评红。思路分类讨论的思维题如果一队有必胜策略,则二队无论如何布置阵形都无法打败一队,则一队必须有一个人攻击值比二队两个人都大,另外一个人防守值比二队两个人防守值都大。if(a1>c2&&a1>d2&&b2>c1&&b2>d1||a2>c1&&a2>d1&&b1>c2&&b1>......
  • 剑指offer面试题3:数组中重复的数字
    一、知识点:数组相关知识二、描述在一个长度为n的数组里的所有数字都在0~n-1范围内,数组中某些数字是重复的,但不知道有几个数字是重复的,也不知道重复几次。请找出数组中任意一个重复的数字,例如:输入长度为7的数组[2,3,2,4,3,3,5],那么输出2或者3都是正确的,存在不合法的输入的话输出-1。......
  • leetcode841钥匙和房间
    使用深度优先遍历构造的图,只要访问过就标记已访问intnum=0;vector<bool>vis;voiddfs(vector<vector<int>>&rooms,intx){vis[x]=true;num++;for(auto&v:rooms[x]){if(!vis[v])dfs(rooms,v);//说明这个房间没有进去过,所以可以访问}}intmai......
  • 剑指 Offer 67. 把字符串转换成整数
    题目链接:剑指Offer67.把字符串转换成整数题目描述:写一个函数StrToInt,实现把字符串转换成整数这个功能。不能使用atoi或者其他类似的库函数。解法思路:直接模拟题代码:funcstrToInt(sstring)int{s=strings.Trim(s,"")minus:=1varansint64=......
  • 剑指 Offer 66. 构建乘积数组
    题目链接:剑指Offer66.构建乘积数组题目描述:**给定一个数组A[0,1,…,n-1],请构建一个数组B[0,1,…,n-1],其中B[i]的值是数组A中除了下标i以外的元素的积,**即B[i]=A[0]×A[1]×…×A[i-1]×A[i+1]×…×A[n-1]。不能使用除法。解法思路:代码:funcconstructArr(a[......
  • 剑指 Offer 65. 不用加减乘除做加法
    题目链接:剑指Offer65.不用加减乘除做加法题目描述:写一个函数,求两个整数之和,要求在函数体内不得使用“+”、“-”、“*”、“/”四则运算符号。解法思路:不用加减乘除,那么可以用位运算代替:可以用a^b运算表示无进位的加法可以用(a&b)<<1表示进位因此a+b=a^b+((a......
  • 剑指 Offer 63. 股票的最大利润
    题目链接:剑指Offer63.股票的最大利润题目描述:假设把某股票的价格按照时间先后顺序存储在数组中,请问买卖该股票一次可能获得的最大利润是多少?解法思路:使用minv记录前i天的最低价格,第i天卖出的利润就是prices[i]-minv,遍历一遍数组,不断更新最大利润代码:funcmaxP......
  • 剑指 Offer 60. n个骰子的点数
    题目链接:剑指Offer60.n个骰子的点数题目描述:把n个骰子扔在地上,所有骰子朝上一面的点数之和为s。输入n,打印出s的所有可能的值出现的概率。解法思路:还未理解代码://通常做法是声明一个二维数组dp,dp[i][j]代表前i个骰子的点数和j的概率,//并执行状态转移。而由于......