zoukankan      html  css  js  c++  java
  • [LeetCode 295] Find Median from Data Stream

    Median is the middle value in an ordered integer list. If the size of the list is even, there is no middle value. So the median is the mean of the two middle value.

    For example,

    [2,3,4], the median is 3

    [2,3], the median is (2 + 3) / 2 = 2.5

    Design a data structure that supports the following two operations:

    • void addNum(int num) - Add a integer number from the data stream to the data structure.
    • double findMedian() - Return the median of all elements so far.

     

    Example:

    addNum(1)
    addNum(2)
    findMedian() -> 1.5
    addNum(3) 
    findMedian() -> 2
    

     

    Follow up:

    1. If all integer numbers from the stream are between 0 and 100, how would you optimize it?
    2. If 99% of all integer numbers from the stream are between 0 and 100, how would you optimize it?

     

    Solution 1. Each time a new number is added, sort the new array and get the median.

    Runtime: Sum of O(i * log i) for i: [1, n]; 

    Space: O(n)

     

    BUD optimization: 

    Bottlenecks: To sort an array arr takes O(arr.length * log arr.length) time.  

    Unecessary work: Sorted the whole array each time even though we don't need all the 

    non-median numbers to be at its right order in the array. 

     

    Solution 2. Apply quick select algorithm to select the new median each time a new number is added.

    Runtime: Sum of O(i) for i: [1, n];

    Space: O(n)

     

    We've improved the bottleneck in solution 1 from O(i * log i) to O(i). But this solution is still not 

    optimal. Can we reduce it even further to log(i)? 

     

    Solution 3. Use a min and max Priority Queue to dynamically maintain the current median. Adding new number

    to a priority queue takes O(log i) time, i is the current number of elements stored in the priority queue.

    Runtime: Sum of O(log i) for i: [1, n], which is approximately O(n * log n)

    Space: O(n)

     

    Use the following invariants to maintain both max and min pq.

     

    The max pq has 1 more element than the min pq if we've processed an odd number of elements;

    They have the same number of elements if we've processed an even number of elements; 

     

    class MedianFinder {
        private PriorityQueue<Integer> maxPq;
        private PriorityQueue<Integer> minPq;
        int size;
        /** initialize your data structure here. */
        public MedianFinder() {
            maxPq = new PriorityQueue<>(Collections.reverseOrder());
            minPq = new PriorityQueue<>();
            size = 0;
        }
        
        public void addNum(int num) {
            if(size == 0) {
                maxPq.add(num);
            }
            else {
                if(num <= maxPq.peek()) {
                    maxPq.add(num);
                }
                else {
                    minPq.add(num);
                }
                if(maxPq.size() - minPq.size() > 1) {
                    minPq.add(maxPq.poll());
                }
                else if(minPq.size() > maxPq.size()) {
                    maxPq.add(minPq.poll());
                }
            }
            size++;
        }
        
        public double findMedian() {
            if(size == 0) {
                return 0.0;
            }
            if(size % 2 != 0) {
                return maxPq.peek();
            }
            double sum = maxPq.peek() + minPq.peek();
            return sum / 2.0;
        }
    }

     

    Related Problems

    Sliding Window Median

    Median

    Median of Two Sorted Arrays 

  • 相关阅读:
    LeetCode 712. Minimum ASCII Delete Sum for Two Strings
    LeetCode 1143. Longest Common Subsequence
    LeetCode 334. Increasing Triplet Subsequence
    Atom支持Markdown和Latex
    使用pudb调试python
    Caffe学习笔记2--Ubuntu 14.04 64bit 安装Caffe(GPU版本)
    Window7下安装Ubuntu 14.04 64bit
    Cnblogs支持Latex及测试
    Caffe学习笔记1--Ubuntu 14.04 64bit caffe安装
    g++编译流程
  • 原文地址:https://www.cnblogs.com/lz87/p/6997513.html
Copyright © 2011-2022 走看看