/*
题目:
链接:https://www.nowcoder.com/questionTerminal/9be0172896bd43948f8a32fb954e1be1
来源:牛客网
如何得到一个数据流中的中位数?如果从数据流中读出奇数个数值,那么中位数就是所有数值排序之后位于中间的数值。
如果从数据流中读出偶数个数值,那么中位数就是所有数值排序之后中间两个数的平均值。
我们使用Insert()方法读取数据流,使用GetMedian()方法获取当前读取数据的中位数。
*/
/*
思路:
将数据流分成两堆,左边一堆的值小于右边一堆的值。
当为奇数个时,中位数为左堆里的最大值;当为偶数个时,中位数为(左堆最大值+右堆最小值)/2.
左堆为最大堆,右堆为最下堆。
*/
#include<iostream>
#include<string.h>
#include<stdio.h>
#include<set>
#include<vector> using namespace std; multiset<int,greater<int>> leftSet;
multiset<int,less<int>> rightSet;
multiset<int,greater<int>>::iterator leftIter;
multiset<int,less<int>>::iterator rightIter;
int myCount = 0;
void Insert(int num)
{ if(myCount % 2 == 0){//当前个数为偶数,将num插到左堆
if(rightSet.empty() || *(rightSet.begin()) >= num){//当右堆为空或右堆最小值大于等于num,直接插入左堆
leftSet.insert(num);
}
else{//当右堆最大值小于num,将右堆最小值放到左堆,将num放到右堆。
rightIter = rightSet.begin();
leftSet.insert(*rightIter);
rightSet.erase(rightIter);
rightSet.insert(num);
}
}else{//当前个数为奇数,将num插到右堆
if(*(leftSet.begin()) <= num){//当左堆最大值小于等于num,直接插入右堆
rightSet.insert(num);
}else{//当左堆最大值大于num,将左堆最大值放到右堆,将num放到左堆。
leftIter = leftSet.begin();
rightSet.insert(*leftIter);
leftSet.erase(leftIter);
leftSet.insert(num);
}
}
myCount++;
} double GetMedian()
{
if(myCount % 2 == 1){
return *(leftSet.begin());
}else{
return ((double)(*(leftSet.begin())) + (double)(*(rightSet.begin())))/2;
} } int main(){ Insert(5); Insert(2);
Insert(3);
Insert(4);
Insert(1);
Insert(6);
Insert(7);
Insert(0);
Insert(8); cout<<GetMedian()<<endl; }

  

剑指offer-面试题41-数据流中的中位数-堆的更多相关文章

  1. 剑指offer(63)数据流中的中位数

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

  2. 【剑指Offer】63、数据流中的中位数

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

  3. 剑指 Offer 41. 数据流中的中位数 + 堆 + 优先队列

    剑指 Offer 41. 数据流中的中位数 Offer_41 题目详情 题解分析 本题使用大根堆和小根堆来解决这个寻找中位数和插入中位数的问题. 其实本题最直接的方法是先对数组进行排序,然后取中位数. ...

  4. 剑指Offer:面试题15——链表中倒数第k个结点(java实现)

    问题描述 输入一个链表,输出该链表中倒数第k个结点.(尾结点是倒数第一个) 结点定义如下: public class ListNode { int val; ListNode next = null; ...

  5. 《剑指offer》面试题41. 数据流中的中位数

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

  6. 剑指offer系列37----数据流中的中位数

    [题目]如何得到一个数据流中的中位数?如果从数据流中读出奇数个数值, * 那么中位数就是所有数值排序之后位于中间的数值. package com.exe8.offer; import java.uti ...

  7. 剑指offer 面试题64 数据流的中位数

    struct cmp { bool operator()(double a, double b) { return a > b; } }; class Solution { public: vo ...

  8. 剑指Offer:面试题29——数组中出现次数超过一半的数字(java实现)

    PS:在前几天的面试中,被问到了这个题.然而当时只能用最低效的方法来解. 问题描述: 数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字.例如输入一个长度为9的数组{1,2,3,2,2,2, ...

  9. 剑指offer 面试题 删除链表中重复的节点

    题目描述 在一个排序的链表中,存在重复的结点,请删除该链表中重复的结点,重复的结点不保留,返回链表头指针. 例如,链表1->2->3->3->4->4->5 处理后 ...

  10. 剑指offer 面试题56. 数组中只出现一次的两个数字

    题目描述 一个整型数组里除了两个数字之外,其他的数字都出现了两次.请写程序找出这两个只出现一次的数字. 方法1:用set记录出现过的数字 class Solution { public: void F ...

随机推荐

  1. js关于时间(date)的比较

    之前在工作上遇到一个问题:使用一些时间插件,如果有俩个时间,要判断结束时间和开始时间的大小?后来就查找了一些资料,这边整理出俩个比较简便的方法. 在这我拿 laydate.js 这个插件来举例: 首先 ...

  2. 2020你还不会Java8新特性?

    Java8(1)新特性介绍及Lambda表达式 前言: 跟大娃一块看,把原来的电脑拿出来放中间看视频用 --- 以后会有的课程 难度 深入Java 8 难度1 并发与netty 难度3 JVM 难度4 ...

  3. Codeforces Gym101234G Dreamoon and NightMarket(优先队列,子集和第k大)

    题意: 求子集和第k大,n,k<=1e6 思路: 优先队列经典题目,注意优先队列是默认按从大到小排的 代码: #include<iostream> #include<cstdi ...

  4. 题解 CF1292A 【NEKO's Maze Game】

    有一个结论: 当 \((1,1)\) 不能抵达 \((2,n)\) 时,必定存在一个点对,这两个点的值均为真,且坐标中的 \(x\) 互异,\(y\) 的差 \(\leq 1\) 这个结论的正确性感觉 ...

  5. 《C# 爬虫 破境之道》:第二境 爬虫应用 — 第五节:小总结带来的优化与重构

    在上一节中,我们完成了一个简单的采集示例.本节呢,我们先来小结一下,这个示例可能存在的问题: 没有做异常处理 没有做反爬应对策略 没有做重试机制 没有做并发限制 …… 呃,看似平静的表面下还是隐藏着不 ...

  6. WebAPI 微信小程序的授权登录以及实现

    这个星期最开始 ,老大扔了2个任务过来,这个是其中之一.下面直接说步骤: 1.  查阅微信开发文档  https://developers.weixin.qq.com/miniprogram/dev/ ...

  7. 2020牛客寒假算法基础集训营4 B:括号序列

    B : 括号序列 考察点 : 栈 坑点 : 只有栈空时才是合法的 Code: #include <stack> #include <cstdio> #include <s ...

  8. python学习(9)字典的基本应用

    字典是一种通过名字或者关键字引用的得数据结构,其键可以是数字.字符串.元组,这种结构类型也称之为映射.字典类型是Python中唯一內建的映射类型.字典可以理解为列表的升级版. dict是无序的 key ...

  9. Keras学习系列——神经网络层组件

    对Keras提供的对各种层的抽象进行相对全面的概括 1 基础常用层 名称 作用 原型参数 Dense 实现全连接层 Dense(units,activation,use_bias=True, kern ...

  10. 面向对象之包装类与Object类

    一.包装类(Wrapper) 1.包装类出现原因 为了使8种基本数据类型的变量具有类的特征,引入包装类 2.类型间转化 ① 基本数据类型---->对应的包装类:自动装箱 包装类---->对 ...