美文网首页
leetcode 295. 数据流的中位数

leetcode 295. 数据流的中位数

作者: topshi | 来源:发表于2019-04-24 14:56 被阅读0次

    题目描述

    中位数是有序列表中间的数。如果列表长度是偶数,中位数则是中间两个数的平均值。
    相关话题: 堆、设计    难度: 困难
    例如,
    [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

    进阶:

    1. 如果数据流中所有整数都在 0 到 100 范围内,你将如何优化你的算法?
    2. 如果数据流中 99% 的整数都在 0 到 100 范围内,你将如何优化你的算法?

    思路:

    • 维系两个堆,一个大顶堆,一个小顶堆。
    • 假设有个数据流 1,3,2,4,3,6,一个数一个数地传输过来,数据将会分布在这两个堆,并且要调整两个堆的大小不能超过1。最后,两个堆的堆顶两个元素是假设将数据流排序后中间相邻的两个数,显而易见,最后中位数有三种情况:1.maxHeap.peek() 2.minHeap.peek() 3.(maxHeap.peek() + minHeap.peek()) / 2.0

    至于一个数据来临应该加到哪个堆:当num < maxHeap.peek(),加入到maxHeap中,否则加入到minHeap,这样才不会破坏堆顶的相邻关系。任意一个堆的大小比另一个堆大2,将较多元素的堆的堆顶弹出来加到较少元素的堆中。

    class MedianFinder {
        private PriorityQueue<Integer> minHeap;
        private PriorityQueue<Integer> maxHeap;
        /** initialize your data structure here. */
        public MedianFinder() {
            this.minHeap = new PriorityQueue<Integer>();
            this.maxHeap = new PriorityQueue<Integer>(new Comparator<Integer>(){
                public int compare(Integer t1, Integer t2){
                    return t2 - t1;
                }
            });
        }
        public void addNum(int num) {
            if(maxHeap.size() > 0 && num < maxHeap.peek()){
                maxHeap.offer(num);
            }else{
                minHeap.offer(num);
            }
            if(minHeap.size() - maxHeap.size() > 1){
                maxHeap.offer(minHeap.poll());
            }else if(maxHeap.size() - minHeap.size() > 1){
                minHeap.offer(maxHeap.poll());
            }
        }
        public double findMedian() {
            if(minHeap.size() > maxHeap.size()){
                return minHeap.peek();
            }else if(maxHeap.size() > minHeap.size()){
                return maxHeap.peek();
            }else{
                return (maxHeap.peek() + minHeap.peek()) / 2.0;
            }
            
        }
    }
    /**
     * Your MedianFinder object will be instantiated and called as such:
     * MedianFinder obj = new MedianFinder();
     * obj.addNum(num);
     * double param_2 = obj.findMedian();
     */
    

    相关文章

      网友评论

          本文标题:leetcode 295. 数据流的中位数

          本文链接:https://www.haomeiwen.com/subject/mkhggqtx.html