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 

  • 相关阅读:
    IDEA 使用 Gradle 创建 Java 项目
    Java HttpsUnits 工具类实现 Https
    Android Thread 常用方法
    Android Handler、Message 常用方法
    Android 透明导航键遮挡布局
    Android 通过 JDBC 连接远程数据库
    python 连接数据库
    备份及更新 Portainer
    secureCRT免密码登陆Linux
    Linux vi 编辑器常见命令的使用
  • 原文地址:https://www.cnblogs.com/lz87/p/6997513.html
Copyright © 2011-2022 走看看