📜  连续数字流的中位数–(使用Set)(1)

📅  最后修改于: 2023-12-03 15:28:20.320000             🧑  作者: Mango

连续数字流的中位数–(使用Set)

简介

本文介绍了一种求解连续数字流的中位数的方法,即使用Set(集合)数据结构。通过将流中的数分为两部分,一个最大堆和一个最小堆,并对两个堆进行合理的维护,最终通过合理的计算可得到流的中位数。

解析

中位数概念

连续数字流的中位数是指,将数字从小到大排序后,排在中间的数字。 例如,流为{5,1,2,4,3},将其排序后为{1,2,3,4,5},其中中位数为3。

方法流程概述

  1. 将连续数字流中的数分为两部分,一个最大堆和一个最小堆。
  2. 最大堆存放的是流中较小的一半数,最小堆存放的是流中较大的一半数。
  3. 保证最大堆中的所有数均小于最小堆中的所有数。
  4. 当流中的数为奇数时,中位数为最大堆的根节点。
  5. 当流中的数为偶数时,中位数为最大堆的根节点和最小堆的根节点的平均值。

代码实现

import heapq

class MedianFinder:
    def __init__(self):
        """
        initialize your data structure here.
        """
        self.min_heap = []  # 最小堆,存放较大的一半数
        self.max_heap = []  # 最大堆,存放较小的一半数

    def addNum(self, num: int) -> None:
        if len(self.max_heap) == len(self.min_heap):
            # 当堆中元素个数相同时,将num插入最大堆
            heapq.heappush(self.max_heap, -num)
            # 将最大堆的根节点插入最小堆,并保证最大堆中的所有数均小于最小堆中的所有数。
            heapq.heappush(self.min_heap, -heapq.heappop(self.max_heap))
        else:
            # 当堆中元素个数相差1时(即最大堆中多一个),将num插入最小堆
            heapq.heappush(self.min_heap, num)
            # 将最小堆的根节点插入最大堆,并保证最大堆中的所有数均小于最小堆中的所有数。
            heapq.heappush(self.max_heap, -heapq.heappop(self.min_heap))

    def findMedian(self) -> float:
        if len(self.max_heap) == len(self.min_heap):
            # 当堆中元素个数为偶数时,中位数为最大堆的根节点和最小堆的根节点的平均值
            return (-self.max_heap[0] + self.min_heap[0]) / 2
        else:
            # 当堆中元素个数为奇数时,中位数为最大堆的根节点
            return -self.max_heap[0]

算法效率

  • 时间复杂度:addNum() 为 O(logn),findMedian() 为 O(1)
  • 空间复杂度: O(n)
总结

本文介绍了一种使用Set(集合)数据结构求解连续数字流的中位数的方法。通过将流中的数分为两部分,一个最大堆和一个最小堆,并对两个堆进行合理的维护,最终通过合理的计算可得到流的中位数。这种方法时间复杂度为 O(logn),空间复杂度为 O(n)。该方法适用于在连续数字流中快速求解中位数的场景,可以应用于海量数据处理的应用场景。