【重点】【队列】295.数据流的中位数

LeetCode 295. 数据流的中位数 - 双堆与平衡树详解 题目描述:设计并实现一个数据结构,支持向数据流中添加整数 addNum(int num) 与查询当前所有元素的中位数 findMedian()。中位数定义:长度为奇数取有序序列中间值,长度为偶数取中间两个数的平均值。原题链接:https://leetcode.cn/problems/find-median-from-data-stream/难度等级:Hard相关标签:设计、堆(优先队列)、平衡树、双堆、数据流。 阅读详情

题目
相同题目:剑指:数据流中的中位数

法1:堆

heap的用法如下:

heapq.heappushpop(heap, item) # 一定会弹出当前堆里「最小」的元素
# heappushpop = 先push → 再pop最小; 而且弹出的一定是: 整个堆里最小的那个值

python基于最大堆,最小堆来做,最大堆,最小堆使用数据结构heapq,该结构默认是最小堆。最大堆实现介绍:
在 Python 的 heapq 模块中,默认实现的是小根堆(最小堆),但可以通过对元素取反的方式,间接实现 最大堆(大根堆)。以下是具体实现方法及示例:
(1)实现原理
数值取反:将元素的值取负数存入堆,使堆顶元素为原数据的最大值。
操作时还原:取出元素后,再次取反恢复原始值。
(2)代码示例

  1. 插入与弹出元素
import heapq

# 初始化最大堆(通过存储负数实现)
max_heap = []
data = [3, 1, 4, 2]

# 插入元素(数值取反)
for num in data:
    heapq.heappush(max_heap, -num)  # 存储负数

# 弹出最大值(取反还原)
largest = -heapq.heappop(max_heap)
print(largest)  # 输出: 4(原数组最大值)

2.直接堆化列表

data = [3, 1, 4, 2]

# 将列表元素取反后堆化
neg_data = [-x for x in data]
heapq.heapify(neg_data)

# 弹出最大值
largest = -heapq.heappop(neg_data)
print(largest)  # 输出: 4

代码实现:

class MedianFinder:

    def __init__(self):
        self.left = []  # 大根堆
        self.right = [] # 小根堆

    def addNum(self, num: int) -> None:
        if len(self.left) == len(self.right): # 向左侧大根堆中添加元素
            heapq.heappush(self.left, -heapq.heappushpop(self.right, num))
        else:                                 # 向右侧小根堆中添加元素
            heapq.heappush(self.right, -heapq.heappushpop(self.left, -num))

    def findMedian(self) -> float:
        if len(self.left) == len(self.right):
            return (self.right[0] - self.left[0]) / 2
        else:
            return -self.left[0]
 
# Your MedianFinder object will be instantiated and called as such:
# obj = MedianFinder()
# obj.addNum(num)
# param_2 = obj.findMedian()

法2:优先队列

优先队列介绍:https://blog.youkuaiyun.com/weixin_73616913/article/details/131361059
必须掌握的算法!!!

class MedianFinder {
    PriorityQueue<Integer> queueBig;
    PriorityQueue<Integer> queueSmall;

    public MedianFinder() {
        queueBig = new PriorityQueue<>((a, b) -> b.compareTo(a));
        queueSmall = new PriorityQueue<>();
    }
    
    public void addNum(int num) {
        if (queueBig.size() == queueSmall.size()) {
            queueSmall.offer(num);
            queueBig.offer(queueSmall.poll());
        } else {
            queueBig.offer(num);
            queueSmall.offer(queueBig.poll());
        }
    }
    
    public double findMedian() {
        if (queueBig.size() != queueSmall.size()) {
            return queueBig.peek();
        } else {
            return ((double) (queueBig.peek() + queueSmall.peek())) / 2.0;
        }
    }
}

力扣第76题:数据流的中位数 是有序整数列表中的中间值。如果列表的大小是偶数,则没有中间值,中位数是两个中间值的平均值。3初始化对象。将num。。与实际答案相差10-5以内的答案将被接受。// 返回 1.5 ((1 + 2) / 2):不断加入新数字:随时返回当前中位数难点在于:数据是的,不是一次性给完。如果每加一个数都重新排序,当然能做,但太慢。所以我们希望有一种结构,能够做到:插入快找中位数也快左边一半:较小的数右边一半:较大的数只要。 阅读详情

相关推荐

通俗解析:霍尔编码器、光电编码器、电位计、磁编码器和旋转变压器的实战选型指南

本文深入解析了霍尔编码器、光电编码器、电位计、磁编码器和旋转变压器五大主流编码器的工作原理与核心特性。通过对比精度、环境耐受性、成本及寿命等关键维度,并结合消费电子、工业自动化、汽车电子及极端环境等典型应用场景,提供了一份清晰的实战选型指南,旨在帮助工程师根据具体需求,在性能、可靠性与成本间做出最优决策。

weixin_29216353的博客 253

【算法入门】力扣题295:数据流的中位数问题的Java与JavaScript解法|LeetCode 295. 数据流的中位数:新手入门指南 (Java & JavaScript)【新手入门】LeetC

https://leetcode.cn/problems/find-median-from-data-stream/description/?envType=study-plan-v2&envId=top-100-liked设计一个数据结构,支持以下两种操作:中位数定义:核心思想:操作流程:::优势: 5. JavaScript代码实现 6. 复杂度分析 方法 addNum 时间复杂度 findMedian 时间复杂度 空间复杂度 暴力排序法 O(1) O(n log n) O(n)

南北极之间 1115

脑机接口(BCI)从原理到开发实战 01|意念控制真的来了?一文看懂脑机接口的技术革命

类型定义典型应用主动式用户主动产生特定思维模式来控制设备运动想象(想象左手/右手移动)反应式用户被动接受外部刺激,系统检测大脑反应P300拼写器、SSVEP(稳态视觉诱发电位)被动式系统监测用户自发脑状态,不要求主动控制疲劳监测、情绪识别、注意力评估本系列后续文章将重点围绕主动式(运动想象)和反应式(P300/SSVEP)展开实战。脑机接口,这个曾经只存在于科幻中的概念,正在政策、资本、技术的三重驱动下,加速从实验室走向产业落地。2026年,注定是脑机接口发展史上浓墨重彩的一年。

小明的博客 1430

LeetCode Hot100 295. 数据流的中位数 MedianFinder

摘要:本文实现了一个MedianFinder类,用于动态计算数据流的中位数。通过维护一个大根堆(存储较小的一半数字)和一个小根堆(存储较大的一半数字),确保大根堆元素数量始终等于或比小根堆多1。添加元素时根据数值大小选择插入堆,并通过平衡操作保持两堆大小关系。查询中位数时,若元素总数为奇数则返回大根堆顶,偶数则返回两堆顶的平均值。该方法保证了插入和查询的时间复杂度均为O(logn)。

2401_87808951的博客 278

Ubuntu单系统安装全攻略:从删除Windows到UEFI引导设置(避坑指南)

本文提供Ubuntu单系统安装的完整指南,涵盖从安全删除Windows系统到UEFI引导设置的详细步骤。通过专业工具准备、分区方案设计、引导加载器配置等关键环节,帮助用户避免常见安装问题,实现纯净高效的Ubuntu单系统环境。特别强调UEFI引导的深度配置与安装后的性能优化,适合希望彻底转向Linux的用户。

weixin_29210727的博客 409

二十八.国民技术MCU开发之UID获取与应用

在国民NT MCU中均有一个96位和128位的唯一设备标识符,其中UCID128 位, UID 为 96 位。手册中描述的作用是:通常用来做为序列号或作为密码,在编写闪存时,将此唯一标识与软件加解密算法相结合,进一步提高代码在闪存存储器内的安全性,也可用于激活带安全功能的自举程序(SecureBootloader)。UCID 和 UID,遵守国民技术芯片序列号定义,它包含芯片生产及版本相关信息。

AIoT深度探索者 | 嵌入式系统架构师 深耕物联网(IoT)与人工智能(AI)融合技术,聚焦​​边缘计算、图像开发、低功耗通信协议​​,致力于智能硬件,关注我获取最新技术文章信息与海量资源~ 1676

LeetCode Hot 100 | 堆/优先队列(C++ 题解)

堆(Heap)是一种完全二叉树,能在 O(log n) 时间完成插入和删除最值操作。本篇涵盖第 K 大元素、前 K 个高频元素和数据流中位数三道经典题目,展示堆在 Top-K 问题和流式数据处理中的应用。题号题目难度核心技巧时间复杂度215第K个最大元素🟡中等随机快速选择,锁定目标位置平均O(n)347前K个高频元素🟡中等哈希计频 + 桶排序O(n)295数据流中位数🔴困难双堆维护,保持大小平衡O(log n)

jcm0903的博客 439

量化交易零基础入门教程

特点 从零开始教编程。靠谱的量化交易学习资源稀少,且具有不讲编程、代码较难、过多等不适合新手等问题,本教程中则会从零开始教编程,解决量化入门过难过编程门槛这一问题。 量化与编程相结合。本教程不仅会教编程,而且会尽量结合量化情景,减少“我要做量化交易为什么要看这些用来培训程序员的东西”的愤懑。 简易精炼,快速入门。尽量只讲最核心最常用的知识,助你快速摆脱想学习量化却处处陌生不知所措的茫然的新手阶段。 读前说明 文后会有自测与自学,包括一些额外的延伸自学内容以及稍有难度的自测题目。 最最最基础的股票.

JanLEE 2885

堆的实现与应用

大顶堆、小顶堆以及相关算法

m0_38137988的博客 223

【unity实战】随机地下城生成3——设置人物移动脚本、动画的切换和摄像机的跟随(含源码)

给房间添加触发器碰撞体,用来判断角色是否进入房间切割人物图片,注意人物每个图片高度可能不同,所有我们需要把轴心调整到人物的底部把人物跑步图片的高度,统一调成20,下面镂空,达到跳跃的效果快速创造人物动画,以人物idle为例,我们选中所有的idle人物图片,拖拽至窗口,unity就会自动生成,并提示保存动画位置别忘记设置人物排序图层,运行人物就动起来了新增run动画设置人物碰撞体设置刚体将重力设置为0,持续人物移动和动画切换的代码设置摄像机跟随单例代码在room中调用。

向宇的博客,专注php/web全栈 unity游戏开发,欢迎大家评论纠错 1052

实战篇(七):使用Processing和PixelFlow库创建交互式流体太极动画

类:用于配置流体运动的参数,比如圆的位置、半径、运动的角度和速度以及颜色等。类:实现了接口,用于更新流体物理仿真的状态,同时整合声音输入作为流体动态变化的一部分。my_update方法:是流体物理仿真更新的核心,它计算流体粒子的速度和位置,并且将这些数据传递给流体库来模拟流动。现在,让我们进一步分析并解释每个部分的作用以及如何操作。float x;// 圆心位置xfloat y;// 圆心位置y// 半径// 是否是顺时针// 圆周运动,弧上的点位置,以及上一帧的点位置// 角度。

帅小柏的博客 1633

LeetCode Hot 100 —— 堆

LeetCode Hot 100 —— 堆

qq_52421969的博客 538

ADAS工作原理解析:如何通过智能技术提升驾驶安全

ADAS通过集成传感器、摄像头、雷达、SoC计算单元以及高效的数据融合技术,提供了一系列主动和被动安全功能,如自动刹车、车道保持、自适应巡航控制等。这些功能共同作用,不仅减少了交通事故的发生,还大幅提升了驾驶员的驾驶体验和安全性。随着技术的进步,ADAS的功能将越来越智能,最终迈向全自动驾驶的未来🚗💨。

weixin_43199439的博客 1148

LeetCode[295]数据流的中位数

解题手段为java语言,有讲解,有源码

月亮被咬碎成星星的博客 445

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

[230601 lc295] 数据流的中位数

我们使用大顶堆和小顶堆的数据结构,把所有数据看成一个有序数组,左半部分存放在大顶堆中,右半部分存放在小顶堆中,并维护大顶堆的大小始终与小顶堆的大小相等,或者大顶堆的大小比小顶堆的大小大 1。在这样的情况下,如果数组大小为奇数,那么大顶堆的堆顶元素就是中位数;如果数组大小为偶数,那么大顶堆的堆顶元素和小顶堆的堆顶元素的均值就是中位数。是有序整数列表中的中间值。如果列表的大小是偶数,则没有中间值,中位数是两个中间值的平均值。在,当向数据结构中加入元素的时候,该怎么加。理解了大顶堆、小顶堆以后代码真的很好写。

Ruchine的博客 213

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

优先级队列(堆)-295.数据流的中位数-力扣(LeetCode)

个人主页:1白天的黑夜1-优快云博客专栏:力扣刷题录_1白天的黑夜1的博客-优快云博客、企鹅程序员:Linux 系统与网络编程_1白天的黑夜1的博客-优快云博客目录一、题目解析1、-105 <= num <= 1052、在调用 findMedian 之前,数据结构中至少有一个元素3、最多 5 * 104 次调用 addNum 和 findMedian二、算法原理解法1:排序直接用sort解法2:借助插入排序的思想解法3:利用大根堆和小根堆维护数据具体过程:三、代码示例解法3:看到最后,如果对您有所帮助

black_bear_white的博客 975

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

LeetCode 295. 数据流的中位数(C++)*

中位数是有序整数列表中的中间值。如果列表的大小是偶数,则没有中间值,中位数是两个中间值的平均值。 MedianFinder() 初始化 MedianFinder 对象。 void addNum(int num) 将数据流中的整数 num 添加到数据结构中。 double findMedian() 返回到目前为止所有元素的中位数。与实际答案相差 10-5 以内的答案将被接受。

Panbk的博客 503

【面试经典 150 | 堆】数据流的中位数

【面试经典 150 | 堆】数据流的中位数 +【优先队列】.

weixin_54383080的博客 1197

求中位数?

优先级队列是一种受限的数据结构,只能从堆顶添加/删除元素,我们的addNum方法可以从堆顶插入元素,但是findMedian函数需要从数据中间取,这个功能优先级队列是没办法提供的。我们可以这样实现,当我们想要往large里添加元素,不能直接添加,而是要先往small里添加,然后再把small的堆顶元素加到large中,向small中添加元素同理。但是,TreeSet是一种Set其中不存在重复元素的元素,但是我们的数据流可能输入重复数据,而且计算中位数也是需要算上重复元素的。

weixin_52055811的博客 1552

295. 数据流的中位数(Median from Data Stream)高质量题解

本文介绍了一种高效计算数据流中位数的双堆算法。通过维护一个大顶堆存储较小的一半元素和一个小顶堆存储较大的一半元素,实现插入操作O(logn)时间复杂度和查询中位数O(1)时间复杂度。关键点在于保持两堆大小平衡(差值不超过1),中位数即为堆顶元素(奇数时取大顶堆顶,偶数时取两堆顶平均值)。这种算法优于暴力排序法,特别适合处理大规模动态数据流,是面试中解决动态中位数问题的经典方案。文中提供了完整的C语言实现代码,包括堆操作和平衡逻辑。

2302_80441878的博客 174

【LeetCode 295】. 数据流的中位数

中位数是有序列表中间的数。如果列表长度是偶数,中位数则是中间两个数的平均值。 例如, [2,3,4] 的中位数是 3 [2,3] 的中位数是 (2 + 3) / 2 = 2.5 设计一个支持以下两种操作的数据结构: void addNum(int num) - 从数据流中添加一个整数到数据结构中。 double findMedian() - 返回目前所有元素的中位数。 示例: addNum(1) addNum(2) findMedian() -> 1.5 addNum(3) findMe.

xuanweiace的博客 314

LeetCode 295. 数据流的中位数|双堆优化解法+逐行代码详解(Python)

摘要:本文详细解析了LeetCode难题「数据流的中位数」,通过双堆(大顶堆+小顶堆)方案高效解决。核心思路是将数据流分成两部分,分别用堆维护,确保快速获取中位数。时间复杂度为O(log n)插入和O(1)查询,完美满足5e4次调用要求。文章包含完整Python代码、复杂度分析、边界测试及常见坑点,特别强调了大顶堆通过负数存储的实现技巧。该解法是算法面试高频考点,适用于实时数据流处理场景。

网络工程师|十多年企业级运维实战|精通 ‌BGP、OSPF、VLAN、SDN、MPLS、ACL、NetFlow、SNMP、 345

力扣347.前K个高频元素、215.数组中的第k个最大元素、295.数据流的中位数

因为这一题需要的是前k个最大的元素,所以最终堆里要保留的是k个最大元素,弹出小的,故使用小顶堆。2. 注意这两个的性质,小顶堆是自顶向下元素变大,大顶堆是自顶向下元素变小,如果取中位数的话,总元素数为偶数就取两个顶堆的第一个元素相加除以2即可,为奇数就取A中第一个元素。添加数字 O(logN) : 堆的插入和弹出操作使用 O(logN) 时间。3. 设元素总数为 N=m+n ,其中 m 和 n 分别为 A 和 B 中的元素个数。1. 分别用小顶堆和大顶堆来存储元素较大的一半和元素较小的一半。

qq_66799283的博客 549

DeepSeek LeetCode.295.数据流的中位数 class MedianFinder Python3

LeetCode 295 题要求设计一个 MedianFinder 类,能够动态添加整数并随时获取当前数据流的中位数。· 时间复杂度:addNum 操作涉及堆的 push 和 pop,均为 O(log n);我们需要始终保持两个堆的大小平衡:要么相等,要么左堆比右堆多一个元素(这样中位数就可以直接从堆顶取出)。· 大顶堆(左半部分):存放较小的一半数,堆顶是这部分的最大值。· 小顶堆(右半部分):存放较大的一半数,堆顶是这部分的最小值。· 空间复杂度:O(n),用于存储所有数据。

m0_37843156的博客 49

LeetCode经典算法面试题 #295:数据流的中位数(双堆法、有序列表、平衡树等多种实现方案详解)

本文讨论了动态数据流中快速计算中位数的问题,提出了三种解决方案。最优解法是使用双堆法(优先队列),将数据分为较小和较大的两部分分别用最大堆和最小堆存储,确保堆大小平衡。插入时间复杂度为O(log n),查询为O(1)。另外两种方法(有序列表二分插入和平衡二叉搜索树)由于效率或实现复杂度问题,不如双堆法实用。双堆法通过优先队列的巧妙组合,高效解决了动态数据流的中位数计算问题。

夏日清风 461

(刷题笔记)查找中位数

查找中位数 295. 数据流的中位数 数组 用一个数组记录所有addNum添加进来的数字,通过插入排序的逻辑保证数组中的元素有序,当调用findMedian方法时,可以通过数组索引直接计算中位数。 但是用数组作为底层容器的问题也很明显,addNum搜索插入位置的时候可以用二分搜索算法,但是插入操作需要搬移数据,所以最坏时间复杂度为 O(N)。 链表 链表插入元素很快,但是查找插入位置的时候只能线性遍历,最坏时间复杂度还是 O(N),而且findMedian方法也需要遍历寻找中间索引,最坏时间复杂度也是 O

qq_36965067的博客 1148
上一篇: 【重点】【单调栈】739.每日温度
下一篇: 【DP】121.买卖股票的最佳时机
Allenlzcoder
博客等级 码龄10年 925粉丝 512原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值