【剑指Offer】面试题64:数据流中的中位数
来源:互联网 发布:知乎名字的由来 编辑:程序博客网 时间:2024/04/26 07:34
整理自剑指Offer
牛客网https://www.nowcoder.com/questionTerminal/9be0172896bd43948f8a32fb954e1be1
一:题目描述
如何得到一个数据流中的中位数?如果从数据流中读出奇数个数值,那么中位数就是所有数值排序之后位于中间的数值。如果从数据流中读出偶数个数值,那么中位数就是所有数值排序之后中间两个数的平均值。
二:解题思路
由于数据从一个数据流中读出来的,数据的数目随着时间的变化而增加,如何选择一个容器存储数据,使插入一个数据后有序 与 计算中位数的时间复杂度性能最优?
如果利用两个指针去寻找中位数
N1N2...N2mN2m+1奇数:P1与P2指向同一个位置
N1N2...N2m偶数:P1,P2指向中间的两个位置(排序后)
整个容器被分成两部分,位于容器左部分的数据比右边的小
P1指向数据左部分最大的数
P2指向数据右边最小的数
如果能够保证数据容器左边的数据小于右边的数据,这样即使左右两边的数据没有排序,也可以根据左边最大的数及右边最小的数得到中位数。
如何快速从一个容器中找到最大的数?----大顶堆实现这个数据容器
如何快速从一个容器中找到最小的数?---小顶堆
要考虑的细节问题:
1.保证数据平均分配在两个堆中:因此两个堆中数目之差不能超过1
2.要保证大顶堆中所有的数据小于小顶堆中的数据
三:代码实现
大顶堆-小顶堆
class Solution {public: vector<int> max;//存放大顶堆 vector<int> min; //存放小顶堆 bool isInvalidInput=false; //当前数据总数为偶数时,插入小顶堆,奇数时,插入大顶堆--保证大顶堆与小顶堆数据平衡 //插入大顶堆前,现将数据插入小顶堆,再将最小值插入到大顶堆中,保证大顶堆元素小于小顶堆元素 //同理,插入小顶堆的元素,现将数据插入到大顶堆,再将最大值插入到小顶堆中,保证小顶堆的元素大于大顶堆元素 void Insert(int num){ //偶数-插入小顶堆 if((min.size()+max.size())%2==0){ //将数据插入大顶堆,找到大顶堆中最大的元素 if(max.size()>0 && num<max[0]){ // push_heap (_First, _Last),要先在容器中加入数据,再调用push_heap () max.push_back(num);//先将元素压入容器 push_heap(max.begin(),max.end(),less<int>());//调整最大堆 num=max[0];//取出最大堆的最大值 //pop_heap(_First, _Last),要先调用pop_heap()再在容器中删除数据 pop_heap(max.begin(),max.end(),less<int>());//删除最大堆的最大值 max.pop_back(); //在容器中删除 } //如果max为空 或者 num大于大顶堆最大值,则将元素直接插入小顶堆 min.push_back(num);//插入小顶堆 push_heap(min.begin(),min.end(),greater<int>());//调整小顶堆 }//if else{ //奇数--插入大顶堆 if(min.size()>0 && num>min[0]){ // push_heap (_First, _Last),要先在容器中加入数据,再调用push_heap () min.push_back(num);//先压入小顶堆 push_heap(min.begin(),min.end(),greater<int>()); //调整小顶堆 num=min[0]; //获得小顶堆最小值 //pop_heap(_First, _Last),要先调用pop_heap()再在容器中删除数据 pop_heap(min.begin(),min.end(),greater<int>()); //删除小顶堆最小值 min.pop_back(); //从容器中删除 } //如果小顶堆为空,或者num小于小顶堆最小值 max.push_back(num); //直接插入大顶堆 push_heap(max.begin(),max.end(),less<int>());//调整大顶堆 } } double GetMedian(){ int size=min.size()+max.size(); if(size<=0) //没有元素,抛出异常 { isInvalidInput=true; return 0; //throw exception("No numbers are available"); } if(size%2==0)//偶数 return (max[0]+min[0])/2.0; else return min[0]; }};
优先队列的方式实现
class Solution {public: priority_queue<int, vector<int>, less<int> > max; //优先队列,less保证队列中元素按照从大到小排列,即队首元素最大 priority_queue<int, vector<int>, greater<int> > min; //有限队列,greater保证队列中元素按照从小到大排列,即队首元素最小 void Insert(int num) { if(max.empty()||num<=max.top()) max.push(num); else min.push(num); //保证max与min中元素个数均衡 if(max.size()==min.size()+2){ min.push(max.top()); max.pop(); } //如果元素个数为奇数,保证max的队首元素为中位数 if(max.size()+1==min.size()){ max.push(min.top()); min.pop(); } } double GetMedian() { return max.size()==min.size()?(max.top()+min.top())/2.0 : max.top(); }};
阅读全文
0 0
- 《剑指Offer》学习笔记--面试题64:数据流中的中位数
- 【剑指Offer学习】【面试题64:数据流中的中位数】
- 剑指offer-面试题64:数据流中的中位数
- 《剑指offer》面试题64 数据流中的中位数
- 剑指offer--面试题64:数据流中的中位数
- 剑指offer-面试题64-数据流中的中位数
- 剑指offer 面试题64 数据流中的中位数
- 剑指offer面试题[64]-数据流中的中位数
- 【剑指Offer】面试题64:数据流中的中位数
- 剑指offer面试题64 数据流中的中位数(Java实现)
- 面试题64:数据流中的中位数
- 面试题64:数据流中的中位数
- 【面试题64】数据流中的中位数
- 面试题64:数据流中的中位数
- 【剑指offer】面试题41:数据流的中位数
- 剑指offer 64-数据流中的中位数
- 《剑指offer》:[64]数据流中的中位数
- 【剑指offer】题64:数据流中的中位数
- 线性渐变,彩虹
- 数据结构实验之链表五:单链表的拆分(栈)
- iOS获取屏幕宽度
- IM-linux一款linux下即时通讯软件实现(一)登陆注册实现
- Spark任务提交jar包依赖解决方案
- 【剑指Offer】面试题64:数据流中的中位数
- 咖啡的合适温度(前缀和以及加减标记)
- Zookeeper使用场景和特性关联
- Linux之chrony时间同步服务配置
- String、StringBuffer与StringBuilder之间区别
- css下拉菜单制作
- Verilog多维数组
- RedHat6.5安装Spark集群
- hdu 5762 (思维 + 暴力)