295. 数据流的中位数(困难)
Posted hequnwang10
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了295. 数据流的中位数(困难)相关的知识,希望对你有一定的参考价值。
一、题目描述
中位数是有序列表中间的数。如果列表长度是偶数,中位数则是中间两个数的平均值。
例如,
[2,3,4] 的中位数是 3
[2,3] 的中位数是 (2 + 3) / 2 = 2.5
设计一个支持以下两种操作的数据结构:
- void addNum(int num) - 从数据流中添加一个整数到数据结构中。
- double findMedian() - 返回目前所有元素的中位数。
示例 1:
addNum(1)
addNum(2)
findMedian() -> 1.5
addNum(3)
findMedian() -> 2
二、解题
两个优先队列
我们用两个优先队列queMax 和 queMin 分别记录大于中位数的数和小于等于中位数的数。当累计添加的数的数量为奇数时,queMin 中的数的数量比queMax 多一个,此时中位数为queMin 的队头。当累计添加的数的数量为偶数时,两个优先队列中的数的数量相同,此时中位数为它们的队头的平均值。
当我们尝试添加一个数num 到数据结构中,我们需要分情况讨论:
- num≤maxqueMin
此时num 小于等于中位数,我们需要将该数添加到queMin 中。新的中位数将小于等于原来的中位数,因此我们可能需要将 queMin 中最大的数移动到queMax 中。
- num>maxqueMin
此时 num 大于中位数,我们需要将该数添加到 queMin 中。新的中位数将大于等于原来的中位数,因此我们可能需要将queMax 中最小的数移动到queMin 中。
class MedianFinder
PriorityQueue<Integer> queMin;
PriorityQueue<Integer> queMax;
public MedianFinder()
queMin = new PriorityQueue<Integer>((a, b) -> (b - a));
queMax = new PriorityQueue<Integer>((a, b) -> (a - b));
public void addNum(int num)
if (queMin.isEmpty() || num <= queMin.peek())
queMin.offer(num);
if (queMax.size() + 1 < queMin.size())
queMax.offer(queMin.poll());
else
queMax.offer(num);
if (queMax.size() > queMin.size())
queMin.offer(queMax.poll());
public double findMedian()
if (queMin.size() > queMax.size())
return queMin.peek();
return (queMin.peek() + queMax.peek()) / 2.0;
时间复杂度:addNum : O(logn);findMedian : O(1);
空间复杂度:O(n)。
以上是关于295. 数据流的中位数(困难)的主要内容,如果未能解决你的问题,请参考以下文章