一、文章标题 LeetCode 295. 数据流的中位数 - 双堆与平衡树详解
二、文章内容
1. 题目概述
- 题目描述:设计并实现一个数据结构,支持向数据流中添加整数 addNum(int num) 与查询当前所有元素的中位数 findMedian()。中位数定义:长度为奇数取有序序列中间值,长度为偶数取中间两个数的平均值。
- 原题链接:https://leetcode.cn/problems/find-median-from-data-stream/
- 难度等级:Hard
- 相关标签:设计、堆(优先队列)、平衡树、双堆、数据流
2. 文章目录
目录
3. 解题思路
- 问题分析:
- 输入:一系列操作 addNum(num)、findMedian();数据流可包含重复值与负数。
- 输出:每次 findMedian() 返回当前数据流中位数(double)。
- 要求:增量更新、频繁查询,需在插入 O(log n) 或更优、查询 O(1) 的综合效率下完成;内存尽量 O(n)。
- 核心难点:
- 动态维护“左半部分最大值”和“右半部分最小值”的平衡关系;
- 正确处理重复元素与偶数个元素时的平均值精度(避免整型溢出/截断);
- 设计清晰的平衡与不变式,确保任意时刻 findMedian 可 O(1) 返回。
- 解题方向:
- 双堆:最大堆保存较小的一半(left),最小堆保存较大的一半(right),保持 |size(left) - size(right)| ≤ 1 且 left 最大值 ≤ right 最小值;
- 双平衡树:用两个 TreeMap 作为多重集合,分别保存左右两半并按计数维护平衡,功能类似双堆但支持按键有序访问;
- 不推荐:每次排序或二分插入到有序数组,插入 O(n) 难以承受。
4. 算法详解
解法一:双堆(最大堆+最小堆)在线维护中位数
算法原理
- 用两个堆维护数据流的两半:
- 大根堆 maxHeap 存放“较小的一半”,堆顶为这一半的最大值;
- 小根堆 minHeap 存放“较大的一半”,堆顶为这一半的最小值。
- 不变式:
- 尺寸平衡:maxHeap.size(


448

被折叠的 条评论
为什么被折叠?



