题目:
如何得到一个数据流中的中位数?如果从数据流中读出奇数个数值,那么中位数就是所有数值排序之后位于中间的数值。如果从数据流中读出偶数个数值,那么中位数就是所有数值排序之后中间两个数的平均值。我们使用Insert()方法读取数据流,使用GetMedian()方法获取当前读取数据的中位数。
分析:
本作一读就知道又是一个套路啊,先排序,再计算。
于是我又召唤了强大的vector,话不多说,上代码!
代码:

class Solution {public:vector<double> a;void Insert(int num) {a.push_back(num);}double GetMedian() { sort(a.begin(),a.end());if(a.size()%2!=0)return a.at(a.size()/2);else{return {(a.at(a.size()/2-1)+a.at(a.size()/2))/2};}}
};

但是,哈哈,这个方法很容易超时~
注意:这次不得不说,奇怪的知识又增加了,通过这道题我是学会了区分size和capatity!之前一直写的是capatity,一直没通过,然后意识到size才是正确的。
size是当前vector容器真实占用的大小,也就是容器当前拥有多少个容器。
capacity是指在发生realloc前能允许的最大元素数,即预分配的内存空间。
当然,这两个属性分别对应两个方法:resize()和reserve()。
使用resize(),容器内的对象内存空间是真正存在的。
使用reserve()仅仅只是修改了capacity的值,容器内的对象并没有真实的内存空间(空间是"野"的)。
此时切记使用[]操作符访问容器内的对象,很可能出现数组越界的问题。
vector 容器的容量(用 capacity 表示),指的是在不分配更多内存的情况下,容器可以保存的最多元素个数;而 vector 容器的大小(用 size 表示),指的是它实际所包含的元素个数。

此时,强大的堆排序要上场了!

class Solution {public:void Insert(int num){if(c % 2 == 0){maxHeap.push(num);minHeap.push(maxHeap.top());maxHeap.pop();}else{minHeap.push(num);maxHeap.push(minHeap.top());minHeap.pop();}c++;}double GetMedian(){ if(c % 2 == 0){return (double)(maxHeap.top() + minHeap.top()) / 2;}else{return (double)minHeap.top();}}
private:priority_queue<int, vector<int>, less<int> > maxHeap;priority_queue<int, vector<int>, greater<int> > minHeap;int c = 0;
};

一个排序数组的中位数可以将数组分成两部分,利用最大堆和最小堆来分别存储这两部分。
要保证最大堆的所有元素小于等于最小堆的元素,在插入元素的时候通过已插入数字数目来判断:
如果插入数目是偶数,就将元素插入最大堆,然后再将最大堆中堆顶元素取出,插入最小堆中。
如果插入数目是奇数,就将元素插入最小堆,然后再将最小堆中堆顶元素取出,插入最大堆中。
这样做就可以保证最大堆的所有元素小于等于最小堆的元素。
然后如果数目是奇数时,中位数等于最小堆的堆顶元素,为偶数时,中位数等于最小堆和最大堆的堆顶元素的平均值。
最小堆 和最大堆
5 [5] []
2 [5] [2]
3 [3,5] [2]
4 [4,5] [3,2]
1 [3,4,5] [2,1]
6 [4,5,6] [3,2,1]
7 [4,5,6,7] [3,2,1]
0 [4,5,6,7] [3,2,1,0]
8 [4,5,6,7,8] [3,2,1,0]

剑指offer——数据流中的中位数相关推荐

  1. [剑指Offer] 数据流中的中位数

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

  2. 剑指offer 矩阵中的路径 @python

    剑指offer 矩阵中的路径 @python 题目描述 请设计一个函数,用来判断在一个矩阵中是否存在一条包含某字符串所有字符的路径.路径可以从矩阵中的任意一个格子开始,每一步可以在矩阵中向左,向右,向 ...

  3. 8. 返回数组里出现次数最多的数字_剑指offer 数组中出现次数超过一半的数字

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

  4. 剑指Offer——链表中倒数第K个节点

    1.题目描述 输入一个链表,输出该链表中倒数第k个结点. 2.代码实现 package com.baozi.offer;/*** @author BaoZi* @create 2019-07-11-1 ...

  5. [剑指Offer]-矩阵中的路径

    题目描述 请设计一个函数,用来判断在一个矩阵中是否存在一条包含某字符串所有字符的路径.路径可以从矩阵中的任意一个格子开始,每一步可以在矩阵中向左,向右,向上,向下移动一个格子.如果一条路径经过了矩阵中 ...

  6. 剑指offer:矩阵中的路径

    题目 请设计一个函数,用来判断在一个矩阵中是否存在一条包含某字符串所有字符的路径.路径可以从矩阵中的任意一个格子开始,每一步可以在矩阵中向左,向右,向上,向下移动一个格子.如果一条路径经过了矩阵中的某 ...

  7. 剑指offer:数组中重复的数字

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

  8. [剑指offer] 数组中只出现一次的数字

    本文首发于我的个人博客:尾尾部落 题目描述 一个整型数组里除了两个数字之外,其他的数字都出现了偶数次.请写程序找出这两个只出现一次的数字. 解题思路 法一:大家都能想到的HashMap法 法二:异或法 ...

  9. 剑指offer 链表中倒数第k个节点

    题目描述 输入一个链表,输出该链表中倒数第k个结点. 解决方案: public class Solution {public ListNode FindKthToTail(ListNode head, ...

最新文章

  1. leetcode 用java_LeetCode算法题-Heaters(Java实现)
  2. 8.图片组件和动画效果--从零起步实现基于Html5的WEB设计器Jquery插件(含源码)...
  3. SpringBoot+MyBatisPlus+Echarts实现查询并显示平均时长占比饼状图
  4. IntelliJ中的远程调试Wildfly应用程序
  5. android node
  6. java 写文件filewriter_使用FileWriter写文件
  7. 无人驾驶(pid算法)
  8. 'htmlentities(): charset `utf8' not supported, assuming utf-8'
  9. 【渝粤教育】国家开放大学2018年春季 0267-21T摄影技术 参考试题
  10. service下载任务
  11. Jtable 表格按多列排序(支持中文汉字排序)
  12. VS2017社区版许可证过期问题
  13. 小团队管理核心(二)
  14. 网络爬虫笔记【4】 掌握获取 Ajax 异步加载网页内容的方法
  15. 通过css和js实现流星雨效果
  16. 访问学者美国访学必须知道十大注意事项
  17. Java中Scanner类的用法
  18. panda3d 键盘移动场景
  19. 微信小程序之input 边框
  20. 用碎玻璃“洗脸”的奇人

热门文章

  1. MVC框架详解(资源整理)
  2. JVET-AC0315:用于色度帧内预测的跨分量Merge模式
  3. 【语音识别】隐马尔可夫模型HMM
  4. 丝网印刷电极 WE AE RE
  5. Elasticsearch报错: received plaintext http traffic on an https channel, closing connection ...
  6. 货拉拉完成 3 亿美元 D 轮融资,2018 年全年业务量增长将近 200%
  7. 单源(多源)最短路算法Dijkstra、Bellman-Ford、SPFA
  8. CT8233LF 是一款电容式单按键触摸检测及接近感应控制芯片
  9. 【RDP】win10家庭版 RDP wrapper 出现 not listening not supported
  10. 免费节点2:使用捷径添加_盒子:找到性能瓶颈的捷径