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 到数据结构中,我们需要分情况讨论:

  1. num≤maxqueMin

此时num 小于等于中位数,我们需要将该数添加到queMin 中。新的中位数将小于等于原来的中位数,因此我们可能需要将 queMin 中最大的数移动到queMax 中。

  1. 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. 数据流的中位数(困难)的主要内容,如果未能解决你的问题,请参考以下文章

LeetCode 295. 数据流的中位数

leetcode| 295. 数据流的中位数

Leetcode 295.数据流的中位数

java 295.从数据流中找到中位数(#)。java

java 295.从数据流中找到中位数(#)。java

java 295.从数据流中找到中位数(#)。java