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

news2024/11/15 4:11:40

题目

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

例如,

[2,3,4] 的中位数是 3

[2,3] 的中位数是 (2 + 3) / 2 = 2.5

设计一个支持以下两种操作的数据结构:

  • void addNum(int num) - 从数据流中添加一个整数到数据结构中。
  • double findMedian() - 返回目前所有元素的中位数。

示例 1:

输入:
["MedianFinder","addNum","addNum","findMedian","addNum","findMedian"]
[[],[1],[2],[],[3],[]]
输出:[null,null,null,1.50000,null,2.00000]

示例 2:

输入:
["MedianFinder","addNum","findMedian","addNum","findMedian"]
[[],[2],[],[3],[]]
输出:[null,null,2.00000,null,2.50000]

限制:最多会对 addNum、findMedian 进行 50000 次调用。


思路

维护两个堆,若n是偶数,它们保存的元素的数目都是n / 2;若n是奇数,大根堆比小根堆多保存一个元素。

一个是大根堆:保存较小的那一部分数;

一个是小根堆:保存较大的那一部分数。

要求中位数

若n是偶数:直接将两个堆的堆顶元素取出,相加除以2即可。

例:[1,2,3,4,5,6]

若n是奇数:(规定大根堆多保存一个元素)直接将大根堆堆顶元素取出即可。

例:[1,2,3,4,5,6,7]

时间复杂度:O(1);

空间复杂度:O(n)。

动态维护(插入操作)

当插入时:

若n是偶数:将要插入的元素添加到小根堆里,再把小根堆堆顶的元素放到大根堆里,这样就进行了动态维护,插入后n为奇数,直接将大根堆堆顶元素取出即可。

若n是奇数:将要插入的元素添加到大根堆里,再把大根堆堆顶的元素放到小根堆里,这样就进行了动态维护,插入后n为偶数,直接将两个堆的堆顶元素取出,相加除以2即可。

时间复杂度:O(logn);

空间复杂度:O(n)。

java使用优先队列实现大根堆和小根堆,默认是小根堆。

小根堆创建

PriorityQueue<Integer> minHeap = new PriorityQueue<>(k, (a, b) -> a - b);

大根堆创建

PriorityQueue<Integer> maxHeap = new PriorityQueue<>(k, (a, b) -> b - a);

其中构造器中的k表示创建堆的大小,之后用Lambda表达式快速实现自定义排序。

Lambda语法

表达式:

(parameters) -> expression

代码块:

(parameters) -> {statements;}

Lambda表达式由三部分组成:

1、paramaters:类似方法中的形参列表,这里的参数是函数式接口里的参数。这里的参数类型可以明确的声明也可不声明而由JVM隐含的推断。另外当只有一个推断类型时可以省略掉圆括号。

2、->:可理解为“被用于”的意思。

3、方法体:可以是表达式也可以代码块,是函数式接口里方法的实现。代码块可返回一个值或者什么都不反回,这里的代码块块等同于方法的方法体。如果是表达式,也可以返回一个值或者什么都不反回。


代码

class MedianFinder {
    Queue<Integer> min, max;

    public MedianFinder() {
        min = new PriorityQueue<>(); //优先级队列默认是小根堆,保存较大的数值
        max = new PriorityQueue<>((x, y) -> (y - x)); //大根堆需要进行重写,保存较小的数值
    }
    
    public void addNum(int num) {
        //是偶数  
        if(min.size() == max.size()) {
            min.add(num);
            max.add(min.poll());
        } else { //是奇数
            max.add(num);
            min.add(max.poll());
        }
    }
    
    public double findMedian() {
        //是偶数
        if(min.size() == max.size()) {
            return (min.peek() + max.peek()) / 2.0;
        } else {
            return max.peek() * 1.0;
        }
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/176941.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

50个常用的 Numpy 函数详解

目录 一、创建数组 1、Array 2、Linspace 3、Arange 4、Uniform 5、Random.randint 6、Random.random 7、Logspace 8、zeroes 9、ones 10、full 11、Identity 二、数组操作 12、min 13、max 14、unique 15、mean 16、medain 17、digitize 18、reshape 19、…

详解1247:河中跳房子(二分经典例题)

1247&#xff1a;河中跳房子【题目描述】每年奶牛们都要举办各种特殊版本的跳房子比赛&#xff0c;包括在河里从一个岩石跳到另一个岩石。这项激动人心的活动在一条长长的笔直河道中进行&#xff0c;在起点和离起点L远 (1 ≤ L≤ 1,000,000,000) 的终点处均有一个岩石。在起点和…

《Unity Shader 入门精要》第6章 Unity 中的基础光照

第6章 Unity 中的基础光照 6.1 我们是如何看到这个世界的 通常来说我们要模拟真实的光照环境来生成一张图像&#xff0c;需要考虑3种物理现象&#xff1a; 首先&#xff0c;光线从光源&#xff08;light source&#xff09;中被发射出来然后&#xff0c;光线和场景中的一些物…

JavaScript while 循环

文章目录JavaScript while 循环while 循环do/while 循环比较 for 和 while笔记列表JavaScript while 循环 只要指定条件为 true&#xff0c;循环就可以一直执行代码块。 while 循环 while 循环会在指定条件为真时循环执行代码块。 语法 while (条件) {需要执行的代码 }本例中…

Redis内部的阻塞式操作以及应对方法

Redis之所以被广泛应用&#xff0c;很重要的一个原因就是它支持高性能访问&#xff0c;也正因为这样&#xff0c;我们必须要重视所有可能影响Redis性能的因素&#xff0c;不仅要知道具体的机制&#xff0c;尽可能避免异常的情况出现&#xff0c;还要提前准备好应对异常的方案。…

MySQL进阶篇之索引2

02、索引 前四节内容&#xff1a;https://blog.csdn.net/kuaixiao0217/article/details/128753999 2.5、SQL性能分析 2.5.1、查看执行频次 1、SQL执行频率 MySQL客户端连接成功后&#xff0c;通过show [session|global] status命令可以提供服务器状态信息。 通过如下指令…

Computer architecture Cyber security Quantum computing交友

如果您也是computer architecture方向的博士硕士&#xff0c;希望交个朋友&#xff0c;欢迎后台私信。 当然&#xff0c;如果您也是 Cyber SecurityQuantum ComputingHigh Performance Computing 方向的博士硕士&#xff0c;想要交流&#xff0c;也可以私信。

学习记录669@项目管理之项目合同管理

有效合同原则 有效合同应具备以下特点: (1)签订合同的当事人应当具有相应的民事权利能力和民事行为能力。 (2)意思表示真实。 (3)不违反法律或社会公共利益 与有效合同相对应&#xff0c;需要避免无效合同。无效合同通常需具备下列任一情形: (1)一方以欺诈、胁迫的手段订立合…

【模拟CMOS集成电路】电路失调与CMRR—— 随机失调与系统失调分析(1)

电路失调与CMRR—— 随机失调与系统失调分析&#xff08;1&#xff09;前言1.1失调1.2失调电路模型1.2.1随机失调电路模型&#xff08;1&#xff09;电阻失配&#xff08;2&#xff09;跨导失配&#xff08;3&#xff09;电流镜的随机失调1.2.2系统失调前言 本文主要内容是失调…

深入剖析JVM垃圾收集器

文章目录前言1、新生代垃圾收集器1.1、Serial1.2、ParNew1.3、Parallel Scavenge2、老年代垃圾收集器2.1、Serial Old2.2、Parallel Old2.3、CMS&#xff08;Concurrent Mark Sweep&#xff09;3、全堆垃圾收集器3.1、Garbage First&#xff08;G1&#xff09;前言 参考资料&am…

ConfigurationProperties将配置绑定到bean的过程分析

概述 ConfigurationProperties是一个大家常用的注解。有一些系统配置&#xff0c;经常放在yml中&#xff0c;然后通过spring注入到bean中。 一般这些配置都是通过在spring生命周期的某一个环节&#xff0c;将属性注入进去的。 ConfigurationProperties就是利用了org.springf…

AC500 基于 Profinet 通讯连接变频器

硬件连接 使用 PM583-ETH 作为 Profinet 通讯的主站&#xff0c;ACS800 变频器 RETA-02 作为 Profinet 通讯的从站 2 ABB 变频器设置 以安装有 RETA-02 总线适配器的 ACS800 变频器为例&#xff0c;参照下表进行参数设定。详 细内容请参考变频器手册和 RETA-02 用户手册。表中…

Python 超强命令行解析工具 argparse !

在工作中&#xff0c;我们经常需要从命令行当中解析出指定的参数&#xff0c;而 Python 也提供了相应的标准库来做这件事情&#xff0c;比如 sys, optparse, getopt, argparse。这里面功能最强大的莫过于 argparse&#xff0c;下面就来看看它用法。import argparse# 使用 argpa…

计算机视觉OpenCv学习系列:第七部分、图像操作-3

第七部分、图像操作-3第一节、图像统计信息1.像素值统计2.函数支持说明3.代码练习与测试第二节、图像直方图1.图像直方图定义2.直方图函数3.代码练习与测试第三节、图像直方图均衡化1.直方图均衡化2.直方图均衡化函数3.代码练习与测试学习参考第一节、图像统计信息 1.像素值统…

零基础学JavaWeb开发(二十一)之 spring框架(4)

3、AOP详解 3.1、Aop常用术语 1.连接点&#xff08;Join point&#xff09;: 连接点表示应用执行过程中能够插入切面的一个点&#xff0c;这个点可以是方法的调用、异常的抛出。在 Spring AOP 中&#xff0c;连接点总是方法的调用。类中的哪些方法可以被增强&#xff0c;这些…

详解动态规划01背包问题--JavaScript实现

对其他动态规划问题感兴趣的&#xff0c;也可以查看详解动态规划最少硬币找零问题--JavaScript实现详解动态规划最长公共子序列--JavaScript实现一开始在接触动态规划的时候&#xff0c;可能会云里雾里&#xff0c;似乎能理解思路&#xff0c;但是又无法准确地表述或者把代码写…

车辆占用应急车道识别抓拍系统 opencv

车辆占用应急车道识别抓拍系统通过opencvpython人工智能识别技术&#xff0c;对高速公路应急车道进行不间断实时监测&#xff0c;当监测到应急车道上有车辆违规占用时&#xff0c;立即告警提醒后台人员及时处理避。OpenCV的全称是Open Source Computer Vision Library&#xff…

【18】C语言 | 数组详解

目录 1、数组的格式 2、下列有什么区别 3、维数组的使用 4、*p 和 int* p arr 的含义 5、二维数组&#xff1a;打印一个二维数组 6、二维数组在数组中的存储 7、数组作为函数参数 8、数组名是数组首元素的地址 1、数组的格式 数组是一组相同类型元素的集合。 数组的创…

20230123英语学习

Interesting Studies to Spark Your Interest in the Research Field 科研也可以很有趣&#xff01;盘点那些好玩的研究 When it comes to picking studies worth reading, what scientists deem an interesting science article might be perceived differently by a person…

【Datewhale一起吃瓜 Task2】啃瓜第三章

文章目录线性模型关键&#xff1a;找到合适的w和b如何找到合适的 w和b&#xff1f;偏导为什么可以&#xff1f;推广线性模型 任务&#xff1a;找出一条线能够对数据进行划分或预测趋势 关键&#xff1a;找到合适的w和b 更适合于连续性的数值&#xff0c;如果数据是离散的如色…