题目:

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

分析:

我们可以想象出一个排序数组的中位数可以将数组分成两部分,那么我们利用最大堆和最小堆来分别存储这两部分,且如果要求中位数时,可以通过直接返回堆顶元素,在O(1)的时间内求解。

要保证最大堆的所有元素小于等于最小堆的元素,在插入元素的时候通过已插入数字数目来判断:

如果插入数目是偶数,就将元素插入最大堆,然后再将最大堆中堆顶元素取出,插入最小堆中。

如果插入数目是奇数,就将元素插入最小堆,然后再将最小堆中堆顶元素取出,插入最大堆中。

这样做就可以保证最大堆的所有元素小于等于最小堆的元素。

然后如果数目是奇数时,中位数等于最小堆的堆顶元素,为偶数时,中位数等于最小堆和最大堆的堆顶元素的平均值。

以[5,2,3,4,1,6,7,0,8]为例:

插入元素 最小堆 最大堆 中位数
5 [5] [] 5
2 [5] [2] 3.5
3 [3,5] [2] 3
4 [4,5] [3,2] 3.5
1 [3,4,5] [2,1] 3
6 [4,5,6] [3,2,1] 3.5
7 [4,5,6,7] [3,2,1] 4
0 [4,5,6,7] [3,2,1,0] 3.5
8 [4,5,6,7,8] [3,2,1,0] 4

程序:

C++

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

Java

import java.util.PriorityQueue;
import java.util.Comparator;
public class Solution { public void Insert(Integer num) {
if(count % 2 == 0){
maxHeap.offer(num);
minHeap.offer(maxHeap.poll());
}else{
minHeap.offer(num);
maxHeap.offer(minHeap.poll());
}
count++;
} public Double GetMedian() {
if(count % 2 == 0){
return new Double(minHeap.peek() + maxHeap.peek()) / 2;
}else{
return new Double(minHeap.peek());
}
}
private PriorityQueue<Integer> minHeap = new PriorityQueue<Integer>();
private PriorityQueue<Integer> maxHeap = new PriorityQueue<Integer>(11, new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
return o2 - o1;
}
});
private int count = 0; }

剑指Offer-62.数据流中的中位数(C++/Java)的更多相关文章

  1. 剑指 Offer 41. 数据流中的中位数 + 堆 + 优先队列

    剑指 Offer 41. 数据流中的中位数 Offer_41 题目详情 题解分析 本题使用大根堆和小根堆来解决这个寻找中位数和插入中位数的问题. 其实本题最直接的方法是先对数组进行排序,然后取中位数. ...

  2. 【剑指Offer】数据流中的中位数 解题报告(Python)

    [剑指Offer]数据流中的中位数 解题报告(Python) 标签(空格分隔): 剑指Offer 题目地址:https://www.nowcoder.com/ta/coding-interviews ...

  3. 【Java】 剑指offer(41) 数据流中的中位数

    本文参考自<剑指offer>一书,代码采用Java语言. 更多:<剑指Offer>Java实现合集   题目 如何得到一个数据流中的中位数?如果从数据流中读出奇数个数值,那么中 ...

  4. Go语言实现:【剑指offer】数据流中的中位数

    该题目来源于牛客网<剑指offer>专题. 如何得到一个数据流中的中位数?如果从数据流中读出奇数个数值,那么中位数就是所有数值排序之后位于中间的数值.如果从数据流中读出偶数个数值,那么中位 ...

  5. 剑指offer:数据流中的中位数(小顶堆+大顶堆)

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

  6. 剑指Offer 63. 数据流中的中位数(其他)

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

  7. 《剑指offer》-数据流中的中位数

    如何得到一个数据流中的中位数?如果从数据流中读出奇数个数值,那么中位数就是所有数值排序之后位于中间的数值.如果从数据流中读出偶数个数值,那么中位数就是所有数值排序之后中间两个数的平均值. 最开始的思路 ...

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

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

  9. 【剑指offer】数据流中的中位数

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

  10. 剑指offer:数据流中的中位数

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

随机推荐

  1. python 内置函数补充 or 递归 or 二分法

    一.内置函数的补充 repr() 显示出字符串的官方表示形式 chr() print(chr(20013)) # 把数字编码转换成字符串 ord() print(ord('中')) # 20013 把 ...

  2. Myeclipse tomcat(jdk)安装

  3. Django ORM------Mysql

    ORM操作 select * from tb where id > 1 #对应关系 models.tb.objects.filter(id__gt=1) models.tb.objects.fi ...

  4. Android中使用Apache common ftp进行下载文件

    版权声明:本文为博主原创文章,未经博主同意不得转载. https://blog.csdn.net/birdsaction/article/details/36379201 在Android使用ftp下 ...

  5. Java中的Runnable、Callable、Future、FutureTask的区别与示例

    Java中存在Runnable.Callable.Future.FutureTask这几个与线程相关的类或者接口,在Java中也是比较重要的几个概念,我们通过下面的简单示例来了解一下它们的作用于区别. ...

  6. 洛谷P2709 小B的询问 莫队

    小B有一个序列,包含N个1~K之间的整数.他一共有M个询问,每个询问给定一个区间[L..R],求Sigma(c(i)^2)的值,其中i的值从1到K,其中c(i)表示数字i在[L..R]中的重复次数.小 ...

  7. C++第5次作业

    运算符重载 定义 - 运算符重载是对已有的运算符赋予多重含义,使同一个运算符作用于不同类型的数据时导致不同行为. 运算符重载规则 - C++运算符除了少数几个,全都可以重载,且只能重载C++已有的运算 ...

  8. CSS3 Box-shadow 阴影效果用法

    一.基本用法: 二.内阴影用法: 三.阴影扩展长度值: box-shadow: 4rpx 4rpx 8rpx #aaa;

  9. 微信小程序wx.request 请求方法

    data: 最终发送给服务器的数据是 String 类型,如果传入的 data 不是 String 类型,会被转换成 String .转换规则如下: 对于 GET 方法的数据,会将数据转换成 quer ...

  10. H3C 配置NAT Server