剑指 Offer 41. 数据流中的中位数

Offer_41

题目详情

题解分析

  1. 本题使用大根堆和小根堆来解决这个寻找中位数和插入中位数的问题。
  2. 其实本题最直接的方法是先对数组进行排序,然后取中位数。但是,这种方法的此方法的时间复杂度为 O(N),其中包括: 查找元素插入位置 O(logN) (二分查找)、向数组某位置插入元素 O(N)(插入位置之后的元素都需要向后移动一位)。
  3. 建立一个 小顶堆 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 为奇数);
  4. 当 m = n(即 N 为 偶数):需向 A 添加一个元素。实现方法:将新元素 num 插入至 B ,再将 B 堆顶元素插入至 A ;

    当 m != n(即 N 为 奇数):需向 B 添加一个元素。实现方法:将新元素 num 插入至 A ,再将 A 堆顶元素插入至 B ;
  5. 当 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. 数据流中的中位数 + 堆 + 优先队列的更多相关文章

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

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

  2. 每日一题 - 剑指 Offer 41. 数据流中的中位数

    题目信息 时间: 2019-06-30 题目链接:Leetcode tag: 大根堆 小根堆 难易程度:中等 题目描述: 如何得到一个数据流中的中位数?如果从数据流中读出奇数个数值,那么中位数就是所有 ...

  3. [剑指offer] 41. 数据流中的中位数 (大小堆,优先队列)

    对于海量数据与数据流,用最大堆,最小堆来管理. class Solution { public: /* * 1.定义一个规则:保证左边(大顶堆)和右边(小顶堆)个数相差不大于1,且大顶堆的数值都小于等 ...

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

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

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

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

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

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

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

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

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

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

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

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

随机推荐

  1. 【noi 2.6_2000】&【poj 2127】 最长公共子上升序列 (DP+打印路径)

    由于noi OJ上没有Special Judge,所以我是没有在这上面AC的.但是在POJ上A了. 题意如标题. 解法:f[i][j]表示a串前i个和b串前j个且包含b[j]的最长公共上升子序列长度 ...

  2. Codeforces Round #650 (Div. 3) D. Task On The Board (构造,贪心)

    题意:有一个字符串和一组数,可以对字符串删去任意字符后为数组的长度,且可以随意排序,要求修改后的字符串的每个位置上的字符满足:其余大于它的字符的位置减去当前位置绝对值之和等于对应序列位置上的数. 题解 ...

  3. 11.PowerShell DSC之安装PowerShell Module

    打开https://powershellgallery.com,检索你需要的目标模块,我们以安装名为"xmysql"的module为例: 自动安装 1.执行命令install-mo ...

  4. Redis Cluster 分布式集群(上)

    Redis Cluster 介绍 Redis 集群是一个可以在多个Redis节点之间进行数据共享的设施(installation): Redis 集群不支持那些需要同时处理多个键的 Redis 命令, ...

  5. leetcode11 盛水容器 贪心

    这道题,总感觉做过... 先理解题意,何为容器 容器 要求水面高度相同 于是体积就是长方形,高度有两块较高板的低板决定,宽度由两块板间距离决定. 考虑当前最优解,就贪心 从两边开始向内,若能使得体积变 ...

  6. print函数与转义字符

    一.print函数 作用:1.输出数字. print(520) 2.输出字符串.(注意:输出字符串要添加单引号.双引号或三引号,告诉编译器可直接输出,不用分析) print('you are so b ...

  7. Ubuntu 18.04 + pip3 install virtualenvwrapper 报错 ERROR: virtualenvwrapper could not find virtualenv in your path

    接上片... 问题 virtualenvwrapper装好后, 发现使用mkvirtualenv XX时, 又找不到virtualenv了... apt install python3-virtual ...

  8. Battery API All In One

    Battery API All In One https://caniuse.com/?search=Battery navigator.getBattery() /* Promise {<pe ...

  9. Android 开启 WebView 页面 Chrome debug

    Android 开启 WebView 页面 Chrome debug WebView debug // 开启 WebView 页面 debug testWebView.setWebContentsDe ...

  10. Kotlin & Android & Swift & Flutter & React Native

    Kotlin & Android https://www.runoob.com/kotlin/kotlin-tutorial.html Swift 5 & iOS 12 https:/ ...