博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
剑指offer:数据流中的中位数
阅读量:6949 次
发布时间:2019-06-27

本文共 2168 字,大约阅读时间需要 7 分钟。

题目描述:

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

 

思路分析:

思路一:最朴素的想法,用一个vector来存输入的数据流。在取中位数的函数中,每次对数据流进行一次排序,对于奇数长度的数据,直接取中间值,对于偶数长度的数据,取中间两个数的平均值。很显然,这个方法是不能令人满意的。对于每一次新加入一个数据后,都需要重新进行一次排序,那么对于n个输入的n次查询,时间复杂度就会达到O(n^2logn),是不可接受的。

 

思路二:实际上,比较多的解法是考虑用堆来实现这个算法,分别维护一个最大堆和一个最小堆。保持两个堆中的数据个数相等,堆内部不需要排序,最大堆中的数始终小于最小堆中的数。同时约定,当总数据个数为偶数时,再有一个数加入,都往最小堆加,加入后,再取出最小堆中的第一个元素即最小值,加入到最大堆中。当为奇数时,先加入最大堆,再将最大堆的首元素即最大值取出加入最小堆。这样,当总数为奇数时,中位数为最大堆中的首元素,当为偶数时,分别取两个堆的首元素再求平均。

 

代码:

思路一:

1 class Solution { 2 public: 3     vector
DataStream; 4 void Insert(int num) 5 { 6 DataStream.push_back(num); 7 } 8 9 double GetMedian()10 { 11 sort(DataStream.begin(), DataStream.end());12 int len = DataStream.size();13 double res;14 if(len%2==1)15 res = DataStream[len/2];16 else17 res = (DataStream[len/2-1]+DataStream[len/2])/2.0;18 return res;19 }20 21 };

 

思路二:

1 class Solution { 2 public: 3     vector
min; 4 vector
max; 5 int count = 0; 6 void Insert(int num) 7 { 8 if(count%2 == 0) 9 {10 min.push_back(num);11 push_heap(min.begin(), min.end(), greater
());12 max.push_back(min[0]);13 push_heap(max.begin(), max.end(), less
());14 pop_heap(min.begin(), min.end(), greater
());15 min.pop_back();16 }17 else18 {19 max.push_back(num);20 push_heap(max.begin(), max.end(), less
());21 min.push_back(max[0]);22 push_heap(min.begin(), min.end(), greater
());23 pop_heap(max.begin(), max.end(), less
());24 max.pop_back();25 }26 count++;27 }28 29 double GetMedian()30 { 31 if(count%2==1)32 return double(max[0]);33 else34 return double((min[0]+max[0])/2.0);35 }36 37 };

 

转载于:https://www.cnblogs.com/LJ-LJ/p/11110015.html

你可能感兴趣的文章
Ext 6.5.3 classic版本,自定义实现togglefield开关控件
查看>>
bzoj1194
查看>>
内购审核被拒-[environment-sandbox]
查看>>
点餐系统最终话--第三次冲刺
查看>>
attachEvent和addEventListener
查看>>
vmware中redhat忘记root密码
查看>>
LINUX 配置SVN
查看>>
怎样设计一个好的数据库
查看>>
go源码分析:strings包
查看>>
Min_25筛学习笔记
查看>>
错误分析:程序集未标记为可序列化
查看>>
禅与文件和文件夹组织的艺术 —— 上
查看>>
Linux自带-系统级性能分析工具 — Perf(转)
查看>>
[HNOI2010]物品调度
查看>>
Keras网络层之常用层Core
查看>>
C# 选择文件、选择文件夹、打开文件(或者文件夹) 路径中获取文件全路径、目录、扩展名、文件名称 追加、拷贝、删除、移动文件、创建目录 修改文件名、文件夹名!!...
查看>>
python学习笔记之——文件I/O
查看>>
【双旦献礼】Portal-Basic Java Web 应用开发框架 v3.0.1 正式发布(源码、示例及文档)...
查看>>
quartz.net的使用
查看>>
split-array-largest-sum(参考了discuss)
查看>>