剑指 Offer 41. 数据流中的中位数 + 堆 + 优先队列
剑指 Offer 41. 数据流中的中位数
Offer_41
题目详情

题解分析
- 本题使用大根堆和小根堆来解决这个寻找中位数和插入中位数的问题。
- 其实本题最直接的方法是先对数组进行排序,然后取中位数。但是,这种方法的此方法的时间复杂度为 O(N),其中包括: 查找元素插入位置 O(logN) (二分查找)、向数组某位置插入元素 O(N)(插入位置之后的元素都需要向后移动一位)。
- 建立一个 小顶堆 A 和 大顶堆 B ,各保存列表的一半元素,且规定:
3.1 A 保存 较大 的一半,长度为 \(\frac{N}{2}\)( N 为偶数)或 \(\frac{N+1}{2}\) ( N 为奇数);
3.2 B 保存 较小 的一半,长度为 \(\frac{N}{2}\)( N 为偶数)或 \(\frac{N-1}{2}\) ( N 为奇数); - 当 m = n(即 N 为 偶数):需向 A 添加一个元素。实现方法:将新元素 num 插入至 B ,再将 B 堆顶元素插入至 A ;
当 m != n(即 N 为 奇数):需向 B 添加一个元素。实现方法:将新元素 num 插入至 A ,再将 A 堆顶元素插入至 B ; - 当 m = n ( N 为 偶数):则中位数为 (小根堆的堆顶元素 + 大根堆的堆顶元素 )/2。
当 m != n( N 为 奇数):则中位数为大根堆的堆顶元素
java代码
package com.walegarrett.offer;
/**
* @Author WaleGarrett
* @Date 2021/2/7 22:03
*/
import java.util.Comparator;
import java.util.PriorityQueue;
/**
* 题目描述:
* 如何得到一个数据流中的中位数?如果从数据流中读出奇数个数值,那么中位数就是所有数值排序之后位于中间的数值。
* 如果从数据流中读出偶数个数值,那么中位数就是所有数值排序之后中间两个数的平均值。
*
*/
public class Offer_41 {
/** initialize your data structure here. */
PriorityQueue<Integer> minHeap,maxHeap;//一个小根堆和一个大根堆,分别存储更大的一半数和存储更小的一半数
public Offer_41() {
minHeap = new PriorityQueue<>();//java默认就是小根堆
maxHeap = new PriorityQueue<>(new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
return o2 - o1;
}
});
}
public void addNum(int num) {
//向小根堆添加一个元素,首先向小根堆添加的元素应该是大根堆中最大的一个元素
if(minHeap.size() == maxHeap.size()){
maxHeap.offer(num);
minHeap.offer(maxHeap.poll());
}else{//向大根堆添加一个元素,向大根堆中添加的元素应该是小根堆中最小的一个元素
minHeap.offer(num);
maxHeap.offer(minHeap.poll());
}
}
/**
* 当 m = n ( N 为 偶数):则中位数为 (小根堆的堆顶元素 + 大根堆的堆顶元素 )/2。
* 当 m != n( N 为 奇数):则中位数为大根堆的堆顶元素。
* @return
*/
public double findMedian() {
if(minHeap.size() == maxHeap.size()){
return (minHeap.peek() + maxHeap.peek()) / 2.0;
}else return minHeap.peek();
}
}
复杂度分析

剑指 Offer 41. 数据流中的中位数 + 堆 + 优先队列的更多相关文章
- 【Java】 剑指offer(41) 数据流中的中位数
本文参考自<剑指offer>一书,代码采用Java语言. 更多:<剑指Offer>Java实现合集 题目 如何得到一个数据流中的中位数?如果从数据流中读出奇数个数值,那么中 ...
- 每日一题 - 剑指 Offer 41. 数据流中的中位数
题目信息 时间: 2019-06-30 题目链接:Leetcode tag: 大根堆 小根堆 难易程度:中等 题目描述: 如何得到一个数据流中的中位数?如果从数据流中读出奇数个数值,那么中位数就是所有 ...
- [剑指offer] 41. 数据流中的中位数 (大小堆,优先队列)
对于海量数据与数据流,用最大堆,最小堆来管理. class Solution { public: /* * 1.定义一个规则:保证左边(大顶堆)和右边(小顶堆)个数相差不大于1,且大顶堆的数值都小于等 ...
- 【剑指Offer】数据流中的中位数 解题报告(Python)
[剑指Offer]数据流中的中位数 解题报告(Python) 标签(空格分隔): 剑指Offer 题目地址:https://www.nowcoder.com/ta/coding-interviews ...
- Go语言实现:【剑指offer】数据流中的中位数
该题目来源于牛客网<剑指offer>专题. 如何得到一个数据流中的中位数?如果从数据流中读出奇数个数值,那么中位数就是所有数值排序之后位于中间的数值.如果从数据流中读出偶数个数值,那么中位 ...
- 剑指offer:数据流中的中位数(小顶堆+大顶堆)
1. 题目描述 /** 如何得到一个数据流中的中位数? 如果从数据流中读出奇数个数值,那么中位数就是所有数值排序之后位于中间的数值. 如果从数据流中读出偶数个数值,那么中位数就是所有数值排序之后中间两 ...
- 剑指Offer 63. 数据流中的中位数(其他)
题目描述 如何得到一个数据流中的中位数?如果从数据流中读出奇数个数值,那么中位数就是所有数值排序之后位于中间的数值.如果从数据流中读出偶数个数值,那么中位数就是所有数值排序之后中间两个数的平均值.我们 ...
- 《剑指offer》-数据流中的中位数
如何得到一个数据流中的中位数?如果从数据流中读出奇数个数值,那么中位数就是所有数值排序之后位于中间的数值.如果从数据流中读出偶数个数值,那么中位数就是所有数值排序之后中间两个数的平均值. 最开始的思路 ...
- [剑指Offer] 63.数据流中的中位数
题目描述 如何得到一个数据流中的中位数?如果从数据流中读出奇数个数值,那么中位数就是所有数值排序之后位于中间的数值.如果从数据流中读出偶数个数值,那么中位数就是所有数值排序之后中间两个数的平均值. c ...
随机推荐
- B、小花梨的三角形(解题报告)
通过set进行标记(思想很简单,实现起来有点容易错)set(红黑树:效率高) 思路: 对行列和长度进行枚举: 对三个顶点进行排序 储存顶点后计数输出 #include<iostream> ...
- zjnu1757Excellent (数学公式)
Description Let us begin with a positive integer N and find the smallest positive integer which does ...
- 2019牛客暑期多校训练营(第四场)k题、j题
传送门 k题: 题意: 给你一串由数字构成的字符串,你从这个字符串中找子字符串使这个字符串是300的倍数 题解: 这道题和第三场的B题极其相似 首先可以把是三百的倍数分开,必须要是100和3的倍数 是 ...
- Codeforces Round #570 (Div. 3) B. Equalize Prices、C. Computer Game、D. Candy Box (easy version)、E. Subsequences (easy version)
B题题意: 给你n个物品的价格,你需要找出来一个值b,使得每一个物品与这个b的差值的绝对值小于k.找到最大的b输出,如果找不到,那就输出-1 题解: 很简单嘛,找到上下限直接二分.下限就是所有物品中最 ...
- MySQL 语句及其种类
DDL(Data Definition Language) DDL(Data Definition Language),数据定义语言 CREATE:创建数据库和表等对象 DROP:删除数据库和表等对象 ...
- Django的settings配置文件
一.邮件配置 EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend' EMAIL_HOST = 'smtp.qq.com' EMAI ...
- unbuntu 安装 bochs
参考 https://www.cnblogs.com/HonkerYblogs/p/10285619.html https://blog.csdn.net/time4/article/details/ ...
- IGS OPC UA 配置
igs项目-右键属性-选择OPC UA,如图配置 ,其他默认 如果打开的是IGS-administration,在右下角会有通知栏图标,右键图标选择 OPC UA 配置 添加服务器节点,网络适配器选择 ...
- Github markdown页面内跳转
基本操作: 请看这里 最典型的就是[alt_content](#jump) 但有时, jump是不太好直接看出来的, 比如下面这个标题, 格式复杂, 那如何获取相应的jump呢? 在Github中, ...
- 设计模式六大原则 All In one
设计模式六大原则 All In one 开闭原则: 对扩展开放,对修改关闭; 设计模式的六大原则: 0.总原则-开闭原则 对扩展开放, 对修改封闭; 在程序需要进行拓展的时候, 不能去修改原有的代码, ...