题目描述

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

分析:大根堆小根堆法

现在假设数组有序,如果我们把数组的前半部分放入一个大根堆,数组的后半部分放入一个小根堆,那么中位数就只能是大根堆的堆顶元素和小根堆的堆顶元素,或者二者堆顶元素的平均值

我们在插入的时候只有遵循某种规则,就能达到这种效果

插入的时候两个堆的元素数量不同,则将新元素插入数量少的堆

若元素数量相同,则随便插入一个堆

若大根堆的堆顶元素大于小根堆的堆顶元素,则交换其堆顶元素

插入完成后,根据元素的数量来确定中位数的值

时间复杂度:插入一个数O(N*log N),获取中位数O(1)

class Solution
{
public: priority_queue<int,vector<int>,less<int> > q1; //大根堆
priority_queue<int,vector<int>,greater<int> > q2; //小根堆 //插入数
void Insert(int um)
{
int x=um; //插入规则
if(q1.size()==q2.size())
{
q2.push(x);
}
else if(q2.size()>q1.size())
{
q1.push(x);
}
else if(q1.size()>q2.size())
{
q2.push(x);
} //根据大根堆小根堆堆顶元素的关系判断是否交换堆顶元素,
//保证堆中的数据是正确的
//(即大根堆保存有序数组前半部分的元素,小根堆保存有序数组后半部分的元素)
if(q1.size()!=0&&q2.size()!=0)
{
if(q1.top()>q2.top())
{
int a=q1.top();
int b=q2.top();
q1.pop();
q2.pop();
q1.push(b);
q2.push(a);
}
}
}
double GetMedian()
{
double x; //根据元素的数量奇偶和元素的分布来求中位数
if(q1.size()==q2.size())
{
x=(q1.top()*1.0+q2.top()*1.0)/2.0;
}
else if(q2.size()>q1.size())
{
x=q2.top()*1.0;
}
else if(q1.size()>q2.size())
{
x=q1.top()*1.0;
}
return x;
}
};

【剑指offer】数据流中的中位数的更多相关文章

  1. 剑指Offer——数据流中的中位数

    题目描述: 如何得到一个数据流中的中位数?如果从数据流中读出奇数个数值,那么中位数就是所有数值排序之后位于中间的数值.如果从数据流中读出偶数个数值,那么中位数就是所有数值排序之后中间两个数的平均值. ...

  2. 剑指Offer-62.数据流中的中位数(C++/Java)

    题目: 如何得到一个数据流中的中位数?如果从数据流中读出奇数个数值,那么中位数就是所有数值排序之后位于中间的数值.如果从数据流中读出偶数个数值,那么中位数就是所有数值排序之后中间两个数的平均值.我们使 ...

  3. 剑指offer--47.数据流中的中位数

    时间限制:1秒 空间限制:32768K 热度指数:122511 算法知识视频讲解 题目描述 如何得到一个数据流中的中位数?如果从数据流中读出奇数个数值,那么中位数就是所有数值排序之后位于中间的数值.如 ...

  4. 剑指offer64 数据流中的中位数

    priority_queue优先级队列,他的模板声明带有三个参数,priority_queue<Type, Container, Functional> Type 为数据类型, Conta ...

  5. 剑指 Offer —— 数组中重复的数字

    数组中的重复数字 题目描述 牛课网链接 长度为 n 的数组里,所有数字都在 0 到 n-1 的范围内. 数组中某些数字是重复的,但不知道有几个数字是重复的.也不知道每个数字重复几次.请找出数组中任意一 ...

  6. 剑指offer 数组中重复的数

    在一个长度为n的数组里的所有数字都在0到n-1的范围内. 数组中某些数字是重复的,但不知道有几个数字是重复的.也不知道每个数字重复几次.请找出数组中任意一个重复的数字. 例如,如果输入长度为7的数组{ ...

  7. 剑指Offer——数组中出现次数超过一半的数字——一题多解

    看题目: 数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字.例如输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}.由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2. ...

  8. 剑指offer——数组中出现次数超过一半的数字(c++)

    题目描述数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字.例如输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}.由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2.如 ...

  9. 剑指Offer 数组中只出现一次的数字

    题目描述 一个整型数组里除了两个数字之外,其他的数字都出现了两次.请写程序找出这两个只出现一次的数字.   思路: 因为有2个数字只出现了一次,而其他的数字都是2次,可以通过异或运算,得到最后这2个只 ...

  10. 剑指Offer 通过中序和先序遍历重建二叉树

    题目描述 输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树.假设输入的前序遍历和中序遍历的结果中都不含重复的数字.例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7, ...

随机推荐

  1. 华为手机usb调试打开后自动关闭怎么办?华为手机 usb调试为什么自动关闭?usb调试老是自动关闭怎么回事?

    01 解决方法一依次点击“设置”——“系统”——“开发人员选项”先开启“开发者选项”开关. 02 然后在开启“USB调试”开关后,一并将“'仅充电'模式下允许ADB调试”选项开关打开.这样,华为手机u ...

  2. web攻击日志分析之新手指

    0x00 前言 现实中可能会经常出现web日志当中出现一些被攻击的迹象,比如针对你的一个站点的URL进行SQL注入测试等等,这时候需要你从日志当中分析到底是个什么情况,如果非常严重的话,可能需要调查取 ...

  3. JavaWeb Listener之HttpSessionActivationListener ,session钝化、活化

    HttpSessionActivationListener    监听HttpSession对象的活化.钝化 钝化:将HttpSession对象从内存中转移至硬盘,存储为.session文件. 活化: ...

  4. python快速生成验证码

    利用python库random,string生成大小写字母和数字的随机验证码 import random import string def generate_code(bit_num): ''' : ...

  5. MySQL主从仅同步指定库

    有两种方式,1.在主库上指定主库二进制日志记录的库或忽略的库: vim /etc/my.cnf ... binlog-do-db=xxxx 二进制日志记录的数据库 binlog-ignore-db=x ...

  6. Linux文件增删改

    Linux目录/文件增删改 创建文件 (1) # touch  <文件名称> (2) 花括号展开 touch /root/{1,3,9}.txt touch /root/{0..100}. ...

  7. 数据库系统概论(新技术篇)--中国人民大学【第13讲】KEY-VALUE数据库(键值对数据库)

    市面上主流的分布式文件系统(FS): (Hadoop的)HDFS,(Google的)GFS     详见ppt   1.数据服务与键值对数据库: 数据服务:data serving数据服务:数据的简单 ...

  8. 洛谷P2463 [SDOI2008]Sandy的卡片(后缀数组SA + 差分 + 二分答案)

    题目链接:https://www.luogu.org/problem/P2463 [题意] 求出N个串中都出现的相同子串的最长长度,相同子串的定义如题:所有元素加上一个数变成另一个,则这两个串相同,可 ...

  9. django 基础1

    1.web应用 本质是基于socket实现的应用程序 浏览器---------服务器 2.http协议:应用层协议 1.基于TCP协议 2.基于请求响应 3.短连接 4.无状态 请求协议 浏览器--- ...

  10. 安装glibc

    wget http://ftp.gnu.org/gnu/glibc/glibc-2.23.tar.gztar -zxvf glibc-2.23.tar.gz cd glibc-2.23 mkdir b ...