剑指offer——数据流中的中位数
题目:
如何得到一个数据流中的中位数?如果从数据流中读出奇数个数值,那么中位数就是所有数值排序之后位于中间的数值。如果从数据流中读出偶数个数值,那么中位数就是所有数值排序之后中间两个数的平均值。我们使用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——数据流中的中位数相关推荐
- [剑指Offer] 数据流中的中位数
题目描述 如何得到一个数据流中的中位数?如果从数据流中读出奇数个数值,那么中位数就是所有数值排序之后位于中间的数值.如果从数据流中读出偶数个数值,那么中位数就是所有数值排序之后中间两个数的平均值. 对 ...
- 剑指offer 矩阵中的路径 @python
剑指offer 矩阵中的路径 @python 题目描述 请设计一个函数,用来判断在一个矩阵中是否存在一条包含某字符串所有字符的路径.路径可以从矩阵中的任意一个格子开始,每一步可以在矩阵中向左,向右,向 ...
- 8. 返回数组里出现次数最多的数字_剑指offer 数组中出现次数超过一半的数字
题目描述 数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字.例如输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}.由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2. ...
- 剑指Offer——链表中倒数第K个节点
1.题目描述 输入一个链表,输出该链表中倒数第k个结点. 2.代码实现 package com.baozi.offer;/*** @author BaoZi* @create 2019-07-11-1 ...
- [剑指Offer]-矩阵中的路径
题目描述 请设计一个函数,用来判断在一个矩阵中是否存在一条包含某字符串所有字符的路径.路径可以从矩阵中的任意一个格子开始,每一步可以在矩阵中向左,向右,向上,向下移动一个格子.如果一条路径经过了矩阵中 ...
- 剑指offer:矩阵中的路径
题目 请设计一个函数,用来判断在一个矩阵中是否存在一条包含某字符串所有字符的路径.路径可以从矩阵中的任意一个格子开始,每一步可以在矩阵中向左,向右,向上,向下移动一个格子.如果一条路径经过了矩阵中的某 ...
- 剑指offer:数组中重复的数字
题目描述 在一个长度为n的数组里的所有数字都在0到n-1的范围内. 数组中某些数字是重复的,但不知道有几个数字是重复的.也不知道每个数字重复几次.请找出数组中任意一个重复的数字. 例如,如果输入长度为 ...
- [剑指offer] 数组中只出现一次的数字
本文首发于我的个人博客:尾尾部落 题目描述 一个整型数组里除了两个数字之外,其他的数字都出现了偶数次.请写程序找出这两个只出现一次的数字. 解题思路 法一:大家都能想到的HashMap法 法二:异或法 ...
- 剑指offer 链表中倒数第k个节点
题目描述 输入一个链表,输出该链表中倒数第k个结点. 解决方案: public class Solution {public ListNode FindKthToTail(ListNode head, ...
最新文章
- leetcode 用java_LeetCode算法题-Heaters(Java实现)
- 8.图片组件和动画效果--从零起步实现基于Html5的WEB设计器Jquery插件(含源码)...
- SpringBoot+MyBatisPlus+Echarts实现查询并显示平均时长占比饼状图
- IntelliJ中的远程调试Wildfly应用程序
- android node
- java 写文件filewriter_使用FileWriter写文件
- 无人驾驶(pid算法)
- 'htmlentities(): charset `utf8' not supported, assuming utf-8'
- 【渝粤教育】国家开放大学2018年春季 0267-21T摄影技术 参考试题
- service下载任务
- Jtable 表格按多列排序(支持中文汉字排序)
- VS2017社区版许可证过期问题
- 小团队管理核心(二)
- 网络爬虫笔记【4】 掌握获取 Ajax 异步加载网页内容的方法
- 通过css和js实现流星雨效果
- 访问学者美国访学必须知道十大注意事项
- Java中Scanner类的用法
- panda3d 键盘移动场景
- 微信小程序之input 边框
- 用碎玻璃“洗脸”的奇人
热门文章
- MVC框架详解(资源整理)
- JVET-AC0315:用于色度帧内预测的跨分量Merge模式
- 【语音识别】隐马尔可夫模型HMM
- 丝网印刷电极 WE AE RE
- Elasticsearch报错: received plaintext http traffic on an https channel, closing connection ...
- 货拉拉完成 3 亿美元 D 轮融资,2018 年全年业务量增长将近 200%
- 单源(多源)最短路算法Dijkstra、Bellman-Ford、SPFA
- CT8233LF 是一款电容式单按键触摸检测及接近感应控制芯片
- 【RDP】win10家庭版 RDP wrapper 出现 not listening not supported
- 免费节点2:使用捷径添加_盒子:找到性能瓶颈的捷径