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)
findMedian() -> 2
进阶:
如果数据流中所有整数都在 0 到 100 范围内,你将如何优化你的算法?
如果数据流中 99% 的整数都在 0 到 100 范围内,你将如何优化你的算法?

学习,代码来自leetcodecn评论

//大堆的元素个数要始终小于等于小堆的元素个数 超值不超过1,大堆的最大值要始终<= 小堆的最小值
class MedianFinder {
    //容量
    private int size;
    //维护较小元素的最大堆
    private PriorityQueue<Integer> maxPQ = new PriorityQueue<>((a,b)->b-a);
    //维护较大的元素的最小堆
    private PriorityQueue<Integer> minPQ = new PriorityQueue<>();
    
    /** initialize your data structure here. */
    public MedianFinder() {    
    }
    
    public void addNum(int num) {
        //插右边
        if (maxPQ.size() > minPQ.size()) {
            minPQ.offer(num);
        } else {
            maxPQ.offer(num);
        }
        size++;
        if (size == 1) return;
        while (maxPQ.peek() > minPQ.peek()) {
                //交换两个极值
                int val1 = maxPQ.poll();
                int val2 = minPQ.poll();
                minPQ.offer(val1);
                maxPQ.offer(val2);
        }  
    }  
    public double findMedian() {
        if (size == 0) return 0;
        if (maxPQ.size() > minPQ.size()) return maxPQ.peek();
        return (maxPQ.peek() + minPQ.peek()) / 2.0;
    }
}

public class PriorityQueue

一个基于优先级堆的无界优先级队列。优先级队列的元素按照其自然顺序进行排序,或者根据构造队列时提供的 Comparator 进行排序,具体取决于所使用的构造方法。优先级队列不允许使用 null 元素。依靠自然顺序的优先级队列还不允许插入不可比较的对象(这样做可能导致 ClassCastException)。
此队列的头 是按指定排序方式确定的最小 元素。如果多个元素都是最小值,则头是其中一个元素——选择方法是任意的。队列获取操作 poll、remove、peek 和 element 访问处于队列头的元素。

猜你喜欢

转载自blog.csdn.net/Fishandbearspaw/article/details/89052442
今日推荐