文章目录
- 1. 题目
- 2. 大小堆解题
1. 题目
中位数是有序列表中间的数。如果列表长度是偶数,中位数则是中间两个数的平均值。
例如,
[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)
findMedian() -> 2进阶:
如果数据流中所有整数都在 0 到 100 范围内,你将如何优化你的算法?
如果数据流中 99% 的整数都在 0 到 100 范围内,你将如何优化你的算法?
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/find-median-from-data-stream
《剑指Offer》同题:面试题41. 数据流中的中位数 链接
2. 大小堆解题
参考我的博客 数据结构 堆(优先队列)
类似题目:
LeetCode 480. 滑动窗口中位数(大小堆升级版+set实现)
LeetCode 703. 数据流中的第K大元素(优先队列)
- 建立大顶堆(存放数据中较小的部分),小顶堆(存放较大的部分)
- 同时维护两个堆的大小相等或者大顶堆多一个
- 那么两个堆的堆顶就是中间的数据,根据奇偶,输出堆顶
class MedianFinder {priority_queue<int> maxHeap;priority_queue<int,vector<int>,greater<int>> minHeap;int n = 0;//数据计数
public:MedianFinder() {}void addNum(int num) {++n;if(maxHeap.size() <= minHeap.size()){if(maxHeap.empty() || num <= minHeap.top())maxHeap.push(num);else//(num > minHeap.top()){maxHeap.push(minHeap.top());minHeap.pop();minHeap.push(num);} }else// maxHeap.size() > minHeap.size(){if(num < maxHeap.top()){minHeap.push(maxHeap.top());maxHeap.pop();maxHeap.push(num);}elseminHeap.push(num);}}double findMedian() {if(n%2 == 1)return maxHeap.top();return (maxHeap.top()+minHeap.top())/2.0;}
};