随机产生数字并传递给一个方法。你能否完成这个方法,在每次产生新值时,寻找当前所有值的中间值(中位数)并保存。

中位数是有序列表中间的数。如果列表长度是偶数,中位数则是中间两个数的平均值。

例如,

[2,3,4] 的中位数是 3
[2,3] 的中位数是 (2 + 3) / 2 = 2.5

设计一个支持以下两种操作的数据结构:
void addNum(int num) – 从数据流中添加一个整数到数据结构中。
double findMedian() – 返回目前所有元素的中位数。

示例:
addNum(1)
addNum(2)
findMedian() -> 1.5
addNum(3)
findMedian() -> 2

Python 解答:
1.列表+二分查找,适合少插入多查询

class MedianFinder:

    def __init__(self):
        """
        initialize your data structure here.
        """
        self.arr = []

    def addNum(self, num: int) -> None:
        i, j = 0, len(self.arr)
        while i < j:
            mid = (i+j) // 2
            if self.arr[mid] < num:
                i = mid+1
            elif self.arr[mid] > num:
                j = mid
            else:
                i = mid
                break
        self.arr.insert(i, num)

    def findMedian(self) -> float:
        length = len(self.arr)
        if length % 2 == 1:
            return self.arr[length//2]
        else:
            return (self.arr[(length-1)//2]+self.arr[(length+1)//2])/2

# Your MedianFinder object will be instantiated and called as such:
# obj = MedianFinder()
# obj.addNum(num)
# param_2 = obj.findMedian()

2.优先队列,大小根堆

import heapq
class MedianFinder:

    def __init__(self):
        """
        initialize your data structure here.
        """
        self.left = []
        self.right = []

    def addNum(self, num: int) -> None:
        if len(self.left) == len(self.right):
            if not self.right or num <= self.right[0]:
                heapq.heappush(self.left, -num)
            else:
                heapq.heappush(self.left, -heapq.heappop(self.right))
                heapq.heappush(self.right, num)
        else:
            if -self.left[0] <= num:
                heapq.heappush(self.right, num)
            else:
                heapq.heappush(self.right, -heapq.heappop(self.left))
                heapq.heappush(self.left, -num)               

    def findMedian(self) -> float:
        if len(self.left) != len(self.right):
            return -self.left[0]
        else:
            return (-self.left[0]+self.right[0])/2

# Your MedianFinder object will be instantiated and called as such:
# obj = MedianFinder()
# obj.addNum(num)
# param_2 = obj.findMedian()
最后修改日期: 2021年5月22日

留言

撰写回覆或留言

发布留言必须填写的电子邮件地址不会公开。