• 剑指Offer41.数据流中的中位数


    题目链接:剑指 Offer 41. 数据流中的中位数

    思路:极大堆、极小堆。因为输入是数据流不是数组,说明输入的数据是不确定的。一般来说先排序,然后返回中间数,但每查询一次就要排序,时间复杂度较高。所以想能不能每次查询都可以直接获取到中间数,而不是对输入的数据排序取中间数。那么,我们就把输入的数据分为两堆,每次输入数据都只会进入两个堆中的一个,而两个堆的中间分界线就是中位数。

    代码:

    class MedianFinder {
        PriorityQueue<Integer> maxHeap, minHeap;
    
        /** initialize your data structure here. */
        public MedianFinder() {
            maxHeap = new PriorityQueue<>((a, b) -> b - a);
            minHeap = new PriorityQueue<>((a, b) -> a - b);
        }
        
        public void addNum(int num) {
            if(maxHeap.isEmpty()){
                maxHeap.offer(num);
                return ;
            }
            if(num <= maxHeap.peek()){
                maxHeap.offer(num);
            }else{
                minHeap.offer(num);
            }
            this.adjust();
        }
        
        public double findMedian() {
            return maxHeap.size()==minHeap.size()?(double)(maxHeap.peek()+minHeap.peek())/2:maxHeap.size() > minHeap.size()?maxHeap.peek():minHeap.peek();
        }
    
        private void adjust(){
            if(maxHeap.size() - minHeap.size() < 2 && maxHeap.size() - minHeap.size() > -2){
                return ;
            }
            if(maxHeap.size() - minHeap.size() >= 2){
                minHeap.offer(maxHeap.poll());
            }
            if(maxHeap.size() - minHeap.size() <= -2){
                maxHeap.offer(minHeap.poll());
            }
        }
    }
    
    /**
     * Your MedianFinder object will be instantiated and called as such:
     * MedianFinder obj = new MedianFinder();
     * obj.addNum(num);
     * double param_2 = obj.findMedian();
     */
    执行用时:75 ms, 在所有 Java 提交中击败了92.29%的用户
    内存消耗:49.8 MB, 在所有 Java 提交中击败了40.09%的用户
  • 相关阅读:
    计算组合数
    UVa11889
    UVa11388
    二分查找
    UVa12096
    UVa156
    UVa400
    京东2017校招编程题
    华为2017秋招测试工程师笔试试卷
    剑指offer第七章&第八章
  • 原文地址:https://www.cnblogs.com/liuyongyu/p/14128098.html
Copyright © 2020-2023  润新知