首页 > 其他分享 >剑指offer——数据流中的中位数

剑指offer——数据流中的中位数

时间:2022-11-01 11:11:05浏览次数:57  
标签:offer maxHeap 中位数 push num 数据流 minHeap size


题目描述:
如何得到一个数据流中的中位数?如果从数据流中读出奇数个数值,那么中位数就是所有数值排序之后位于中间的数值。如果从数据流中读出偶数个数值,那么中位数就是所有数值排序之后中间两个数的平均值。我们使用Insert()方法读取数据流,使用GetMedian()方法获取当前读取数据的中位数。

思路:设想,如果是一个排序数组,则中位数是中间的一个数(奇数)或两个数(偶数)。

剑指offer——数据流中的中位数_中位数


如上图所示,排序数组,个数是奇数时,中位数是中间的一个数,个数是偶数时,中位数是中间两个数的平均值。也可以这样想,中位数是左边排序数组的最大值,右边排序数组的最小值。既然这样,左右元素是否排序就不重要了,只要保证左边的数值都比右边的数值小就可以了,这样只需要查找到左边的最大值和右边的最小值即可。

找最大值和最小值,用最大堆和最小堆来实现。具体细节在注释里说明了

class Solution {
public:
void Insert(int num)
{
if(((minHeap.size()+maxHeap.size())&1)==0){//当前数字个数是偶数时,最终应该插入到minHeap
if(maxHeap.size()>0&&num<maxHeap[0]){//挑选maxHeap中最大的元素添加到minHeap中
maxHeap.push_back(num);
push_heap(maxHeap.begin(),maxHeap.end(),less<int>());//保持最大堆
num=maxHeap[0];
pop_heap(maxHeap.begin(),maxHeap.end(),less<int>());
maxHeap.pop_back();
}
minHeap.push_back(num);
push_heap(minHeap.begin(),minHeap.end(),greater<int>());
}else{//当前数字个数是奇数时,最终应该插入到maxHeap中
if(minHeap.size()>0&&num>minHeap[0]){//挑选minHeap中最小的元素添加到maxHeap中
minHeap.push_back(num);
push_heap(minHeap.begin(),minHeap.end(),greater<int>());
num=minHeap[0];
pop_heap(minHeap.begin(),minHeap.end(),greater<int>());
minHeap.pop_back();
}
maxHeap.push_back(num);
push_heap(maxHeap.begin(),maxHeap.end(),less<int>());
}
}

double GetMedian()
{
double res;
if(minHeap.size()+maxHeap.size()<1)
return 0.0;
if(((minHeap.size()+maxHeap.size())&1)==1)
res=minHeap[0];
else
res=(minHeap[0]+maxHeap[0])/2.0;//在做除法的时候需要注意,被除数要是浮点数,最终结果才能得到浮点数
return res;
}
private:
vector<int> minHeap;
vector<int> maxHeap;
};


标签:offer,maxHeap,中位数,push,num,数据流,minHeap,size
From: https://blog.51cto.com/u_15855860/5812285

相关文章

  • 剑指offer——整数中1出现的次数
    题目描述:求出113的整数中1出现的次数,并算出1001300的整数中1出现的次数?为此他特别数了一下1~13中包含1的数字有1、10、11、12、13因此共出现6次,但是对于后面问题他就没辙......
  • 剑指offer——数字在排序数组中出现的次数
    题目描述:统计给定数字k在排序数组中出现的次数思路1:最容易想到但是效率不高的一个方法就是遍历整个数组,统计k出现的次数(for循环就能解决,不赘述)思路2:由于题目给出是排序......
  • 剑指offer——二叉树的深度
    题目描述:输入一棵二叉树,求该树的深度。从根结点到叶结点依次经过的结点(含根、叶结点)形成树的一条路径,最长路径的长度为树的深度。思路1:按照深度优先遍历,设置一个全局变量ma......
  • 剑指offer——不用加减乘除做加法
    题目描述:写一个函数,求两个整数之和,要求在函数体内不得使用+、-、*、/四则运算符号。思路:分三步1)不考虑进位,只是对两个数进行按位异或(二进制异或就是对应位相加)2)统计进......
  • 剑指offer——圆圈中最后剩下的数字
    题目描述:每年六一儿童节,牛客都会准备一些小礼物去看望孤儿院的小朋友,今年亦是如此。HF作为牛客的资深元老,自然也准备了一些小游戏。其中,有个游戏是这样的:首先,让小朋......
  • 剑指offer——求1+2+3+...+n的和
    题目描述:求1+2+3+…+n,要求不能使用乘除法、for、while、if、else、switch、case等关键字及条件判断语句(A?B:C)思路1:使用构造函数,创建n个类对象,利用构造函数进行求和计算clas......
  • 剑指offer——扑克牌中的顺子
    题目描述:LL今天心情特别好,因为他去买了一副扑克牌,发现里面居然有2个大王,2个小王(一副牌原本是54张_)…他随机从中抽出了5张牌,想测测自己的手气,看看能不能抽到顺子,如......
  • 取m和n的中位数溢出解决办法
    在LeetCode上刷一道二分的简单题,需要计算m和n的中位数。通常的想法是直接如下即可:intmid=(m+n)/2;然而​​mid​​​存在溢出的风险,一种简单的解决办法是把​​mid......
  • 剑指Offer-03-数组中重复的数字
    剑指Offer-03数组中重复的数字描述在一个长度为n的数组里的所有数字都在0到n-1的范围内。数组中某些数字是重复的,但不知道有几个数字是重复的。也不知道每个数字重复几......
  • Java语言的过滤数据流
    过滤数据流为了解决不同数据流之间速度、数据格式差异的问题,以便提高输入/输出操作的效率(特别是当需要大量的输入、输出操作的程序时),因此,Java贴心的提供了过滤流。在已存在......