【剑指offer-解题系列(64)】数据流中的中位数
来源:互联网 发布:遥远地球之歌 知乎 编辑:程序博客网 时间:2024/06/03 10:50
题目描述
如何得到一个数据流中的中位数?如果从数据流中读出奇数个数值,那么中位数就是所有数值排序之后位于中间的数值。如果从数据流中读出偶数个数值,那么中位数就是所有数值排序之后中间两个数的平均值。
分析
使用两个堆排数组,一个最大堆(前半段数据),一个最小堆(后半段数据)。
两个堆总共只有两种情况:
1、最大堆和最小堆数量相等(此时返回两个堆顶数目的相加平均)
2、最小堆数量多一个(返回最小堆顶元素)
如果新来的数字大于最小堆堆顶(属于后半段),那么塞入后半段数组
如果新来的属于前半段,塞入前半段数组
如果发现两边数目不均衡(最小堆-最大堆数目 超过1),则将进行最小堆顶元素给到最大堆,并且调整两个堆
代码实现
vector<int>min_half; // 最大堆
vector<int>max_half; // 最小堆
void Insert(int num)
{
if(min_half.size()<=0){
min_half.push_back(num);
return;
}
if(max_half.size()<=0){
max_half.push_back(num);
if(max_half[0]<min_half[0])swap(max_half[0],min_half[0]);
return;
}
if(min_half.size()==max_half.size()){
if(num>min_half[0]){
min_half.push_back( min(num,max_half[0]));
max_half[0]=max(num,max_half[0]);
HeapAdjustMax(min_half,0,min_half.size()-1);
HeapAdjustMin(max_half,0,max_half.size()-1);
}
else{
min_half.push_back(num);
HeapAdjustMax(min_half,0,min_half.size()-1);
}
}
else{
if(num>min_half[0]){
max_half.push_back(num);
HeapAdjustMin(max_half,0,max_half.size()-1);
}
else{
max_half.push_back( max(num,min_half[0]));
min_half[0]=min(num,max_half[0]);
HeapAdjustMax(min_half,0,min_half.size()-1);
HeapAdjustMin(max_half,0,max_half.size()-1);
}
}
}
double GetMedian()
{
if(min_half.size()==max_half.size()+1){
return min_half[0];
}
else
return 0.5*min_half[0]+0.5*max_half[0];
}
void HeapAdjustMax(vector<int>&a,int start,int end){
if(start>=end)
return ;
for(int i =end;i>=start;i--){
int left = 2*i+1;
int right= 2*i+2;
if(left<=end){
if(right<=end){
if(a[right]>a[left] && a[right]>a[i])
swap(a[i],a[right]);
else if(a[left]>a[i] && a[left]>a[right])
swap(a[i],a[left]);
}
else
if(a[left]>a[i])
swap(a[i],a[left]);
}
}
}
void HeapAdjustMin(vector<int>&a,int start,int end){
if(start>=end)
return ;
for(int i =end;i>=start;i--){
int left = 2*i+1;
int right= 2*i+2;
if(left<=end){
if(right<=end){
if(a[right]<a[left] && a[right]<a[i])
swap(a[i],a[right]);
else if(a[left]<a[i] && a[left]<a[right])
swap(a[i],a[left]);
}
else
if(a[left]<a[i])
swap(a[i],a[left]);
}
}
}
vector<int>max_half; // 最小堆
void Insert(int num)
{
if(min_half.size()<=0){
min_half.push_back(num);
return;
}
if(max_half.size()<=0){
max_half.push_back(num);
if(max_half[0]<min_half[0])swap(max_half[0],min_half[0]);
return;
}
if(min_half.size()==max_half.size()){
if(num>min_half[0]){
min_half.push_back( min(num,max_half[0]));
max_half[0]=max(num,max_half[0]);
HeapAdjustMax(min_half,0,min_half.size()-1);
HeapAdjustMin(max_half,0,max_half.size()-1);
}
else{
min_half.push_back(num);
HeapAdjustMax(min_half,0,min_half.size()-1);
}
}
else{
if(num>min_half[0]){
max_half.push_back(num);
HeapAdjustMin(max_half,0,max_half.size()-1);
}
else{
max_half.push_back( max(num,min_half[0]));
min_half[0]=min(num,max_half[0]);
HeapAdjustMax(min_half,0,min_half.size()-1);
HeapAdjustMin(max_half,0,max_half.size()-1);
}
}
}
double GetMedian()
{
if(min_half.size()==max_half.size()+1){
return min_half[0];
}
else
return 0.5*min_half[0]+0.5*max_half[0];
}
void HeapAdjustMax(vector<int>&a,int start,int end){
if(start>=end)
return ;
for(int i =end;i>=start;i--){
int left = 2*i+1;
int right= 2*i+2;
if(left<=end){
if(right<=end){
if(a[right]>a[left] && a[right]>a[i])
swap(a[i],a[right]);
else if(a[left]>a[i] && a[left]>a[right])
swap(a[i],a[left]);
}
else
if(a[left]>a[i])
swap(a[i],a[left]);
}
}
}
void HeapAdjustMin(vector<int>&a,int start,int end){
if(start>=end)
return ;
for(int i =end;i>=start;i--){
int left = 2*i+1;
int right= 2*i+2;
if(left<=end){
if(right<=end){
if(a[right]<a[left] && a[right]<a[i])
swap(a[i],a[right]);
else if(a[left]<a[i] && a[left]<a[right])
swap(a[i],a[left]);
}
else
if(a[left]<a[i])
swap(a[i],a[left]);
}
}
}
阅读全文
0 0
- 【剑指offer-解题系列(64)】数据流中的中位数
- 剑指offer 64-数据流中的中位数
- 《剑指offer》:[64]数据流中的中位数
- 【剑指offer】题64:数据流中的中位数
- 剑指offer(60)-数据流中的中位数
- 剑指offer--数据流中的中位数
- 《剑指offer》数据流中的中位数
- 剑指offer:数据流中的中位数
- 剑指offer-数据流中的中位数
- 剑指offer 数据流中的中位数
- 《剑指offer》数据流中的中位数
- 剑指Offer:数据流中的中位数
- 剑指offer-数据流中的中位数
- 剑指offer 数据流中的中位数
- 剑指offer系列之六十二:数据流中的中位数
- 《剑指Offer》学习笔记--面试题64:数据流中的中位数
- 【剑指Offer学习】【面试题64:数据流中的中位数】
- 剑指offer-面试题64:数据流中的中位数
- 【数据科学】当代数据科学家需要掌握的技能
- linux下tomcat常用操作
- spark和hadoop的区别
- Android 文件上传的几种方式
- 错误"error while loading shared libraries: xxx.so.x" 的原因和解决办法
- 【剑指offer-解题系列(64)】数据流中的中位数
- IIC协议和应用程序访问
- 命令行执行Jmeter
- feign-底层http请求组件剖析
- nodejs 动态加载模块 _compile
- 微信放大招,和整个互联网为敌?
- python2.7基于selenium的web自动化测试项目--contract
- 如何将pdf等非标准数据文件转换成可供EXCEL等软件分析的数据
- 软键盘(挡住button,和点击外部软键盘消失)