• [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

    此题要找出数据流的中位数,数据流由无序整数组成,并且数据流是在变化的。中位数的定义是,如果数字个数为偶数,中位数就是中间两个数的平均数,如果是奇数,中位数是中间那个数字。

    解法1: 最简单的想法是,每进来一个数字后,插入排序整个数组,保持数组是有序的,然后分奇偶的情况找到中位数。此方法不高效。

    解法2: 堆Heap,将进来的数据流分成大小两个堆,分别保存堆的前半部分和后半部分,大堆是最小数字在堆顶,小堆是最大数在堆顶。取中间值时,根据两个堆的数字个数,如果个数相同,就各取堆顶数字取平均数就是中间数,如果有一个堆数字多1,中间数就是这个堆顶数字。

    Java:

    class MedianFinder {
        PriorityQueue<Integer> maxHeap;//lower half
        PriorityQueue<Integer> minHeap;//higher half
     
        public MedianFinder(){
            maxHeap = new PriorityQueue<Integer>(Collections.reverseOrder());
            minHeap = new PriorityQueue<Integer>();
        }
     
        // Adds a number into the data structure.
        public void addNum(int num) {
            maxHeap.offer(num);
            minHeap.offer(maxHeap.poll());
     
            if(maxHeap.size() < minHeap.size()){
                maxHeap.offer(minHeap.poll());
            }
        }
     
        // Returns the median of current data stream
        public double findMedian() {
            if(maxHeap.size()==minHeap.size()){
                return (double)(maxHeap.peek()+(minHeap.peek()))/2;
            }else{
                return maxHeap.peek();
            }
        }
    } 

    Python:

    from heapq import heappush, heappop
    
    class MedianFinder:
        def __init__(self):
            """
            Initialize your data structure here.
            """
            self.__max_heap = []
            self.__min_heap = []
    
        def addNum(self, num):
            """
            Adds a num into the data structure.
            :type num: int
            :rtype: void
            """
            # Balance smaller half and larger half.
            if not self.__max_heap or num > -self.__max_heap[0]:
                heappush(self.__min_heap, num)
                if len(self.__min_heap) > len(self.__max_heap) + 1:
                    heappush(self.__max_heap, -heappop(self.__min_heap))
            else:
                heappush(self.__max_heap, -num)
                if len(self.__max_heap) > len(self.__min_heap):
                    heappush(self.__min_heap, -heappop(self.__max_heap))
    
        def findMedian(self):
            """
            Returns the median of current data stream
            :rtype: float
            """
            return (-self.__max_heap[0] + self.__min_heap[0]) / 2.0 
                   if len(self.__min_heap) == len(self.__max_heap) 
                   else self.__min_heap[0]
    

    C++:

    class MedianFinder {
    public:
    
        // Adds a number into the data structure.
        void addNum(int num) {
            small.push(num);
            large.push(-small.top());
            small.pop();
            if (small.size() < large.size()) {
                small.push(-large.top());
                large.pop();
            }
        }
    
        // Returns the median of current data stream
        double findMedian() {
            return small.size() > large.size() ? small.top() : 0.5 *(small.top() - large.top());
        }
    
    private:
        priority_queue<long> small, large;
    };
    

      

       

    All LeetCode Questions List 题目汇总

  • 相关阅读:
    Android UI(四)云通讯录项目之云端更新进度条实现
    [Java 泥水匠] Java Components 之一:Java String (肯定有你不懂的)
    Android UI(三)SlidingMenu实现滑动菜单(详细 官方)
    Android UI(二)DridView的菜单
    Android UI(一)Layout 背景局部Shape圆角设计
    Singly linked list algorithm implemented by Java
    Servlet JSP 二重修炼:Filter过滤器
    HDU 1006 Digital Roots
    2012-2014 三年浙江 acm 省赛 题目 分类
    HDU 1006 Tick and Tick 时钟指针问题
  • 原文地址:https://www.cnblogs.com/lightwindy/p/9491207.html
Copyright © 2020-2023  润新知