剑指offer第二版(Python3)--面试题41 : 数据流中的中位数

第2章 面试需要的基础知识

第3章 高质量的代码

第4章 解决面试题的思路

第5章 优化时间和空间效率

  面试题39 : 数组中出现次数超过一半的数字

  面试题40 : 最小的k个数

  面试题41 : 数据流中的中位数

  面试题42 : 连续子数组的最大和

第6章 面试中的各项能力

第7章 两个面试案例


题目描述
牛客网
  如何得到一个数据流中的中位数?如果从数据流中读出奇数个数值,那么中位数就是所有数值排序之后位于中间的数值。如果从数据流中读出偶数个数值,那么中位数就是所有数值排序之后中间两个数的平均值。我们使用Insert()方法读取数据流,使用GetMedian()方法获取当前读取数据的中位数。

解题思路
  如果数组是排序的,那么中间位即是中位数。插入数据到排序数组中时间复杂度是O(n)。
  如果数组左边的数据都小于右边的数据,那么即使左右两边内部数据没有排序,也可以根据左边最大的数及右边最小的数得到中位数。因此用一个最大堆存储左边的数,最小堆存储右边的数,左右两边数的数量相差不超过1。
  利用Python的heapq库实现最大堆和最小堆。

原则:
  维持最大堆长度大于等于最小堆长度,且长度差最大为1。

  1. 任何情况下,数据先插入最大堆,然后抛出最大堆中最大值到最小堆中;
  2. 若最大堆长度小于最小堆长度,则从最小堆中抛出最小值到最大堆中。

实战

import heapq
class Solution:
    def __init__(self):
        self.min_heap = []
        self.max_heap = []
        
    def Insert(self, num):
        # write code here
        heapq.heappush(self.min_heap, -heapq.heappushpop(self.max_heap, -num))
        if len(self.max_heap) < len(self.min_heap):
            heapq.heappush(self.max_heap, -heapq.heappop(self.min_heap))
            
    def GetMedian(self, n=None):
        # write code here
        if not self.min_heap and not self.max_heap:
            return None
        if len(self.max_heap) > len(self.min_heap):
            return -self.max_heap[0]
        else:
            return (self.min_heap[0] - self.max_heap[0]) / 2.0

你可能感兴趣的:(算法设计)