Harukaze

 

【力扣】浅析Pythonのheapq包&求中位数巧妙应用

今日刷力扣偶然刷到使用heapq包简便解决中位数问题,记录下

首先简要介绍主要语句功能

 1 from heapq import *
 2 a=[2,7,4,0,8,12,14,13,10,3,4]
 3 heapify(a)   #自动将列表转为小根堆
 4 heappush(a,9) #添加9进入堆
 5 a
 6 [0, 2, 4, 7, 3, 9, 14, 13, 10, 8, 4, 12]
 7 heappop(a)  #堆最小元素出栈
 8 0
 9 b=a.copy()
10 heappushpop(a,6)    
11 #输出2
12 heapreplace(b,6) 
13 #输出2
14 a
15 #[3, 4, 4, 7, 6, 9, 14, 13, 10, 8, 12]
16  b
17 #[3, 4, 4, 7, 6, 9, 14, 13, 10, 8, 12]
18 heappushpop(a, -1)#元素-1入栈,最小元素出栈,(再弹出最小值之前,将-1推送到堆上)
19 #输出-1
20 heapreplace(b, -1)#返回b中的最小值,不管x的值如何
21 #输出

题目描述:

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/find-median-from-data-stream

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

例如,

[2,3,4] 的中位数是 3

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

设计一个支持以下两种操作的数据结构:

void addNum(int num) - 从数据流中添加一个整数到数据结构中。
double findMedian() - 返回目前所有元素的中位数。

class MedianFinder:

    def __init__(self):
        """
        initialize your data structure here.
        """
        self.minheap = []
        self.maxheap = []
        
    def addNum(self, num: int) -> None:
        heappush(self.minheap, -heappushpop(self.maxheap, -num))
        if len(self.minheap) > len(self.maxheap):
            heappush(self.maxheap, -heappop(self.minheap))

    def findMedian(self) -> float:
        if len(self.maxheap) > len(self.minheap):
            return -self.maxheap[0]
        return (self.minheap[0] - self.maxheap[0]) / 2
作者:elevenxx
链接:https://leetcode-cn.com/problems/find-median-from-data-stream/solution/zui-da-zui-xiao-dui-by-elevenxx/

添加元素过程

假设 addNum(1),addNum(2),addNum(3),addNum(2)

addNum(1)执行结果 self.minheap=[], self.maxheap=[-1]

过程分析:初始minheap与maxheap均为空,minheap顺利添加元素1,执行if语句后,minheap中的元素1出堆,添加负号加入到最大堆中

addNum(2), self.minheap=[2], self.maxheap = [-1]

过程分析:元素-num(-2),添加入maxheap后又立刻出堆,再取负号(2),添加入minheap,不满足if语句

addNum(3), self.minheap=[3], self.maxheap=[-2,-1]

过程分析:元素-num(-3),添加入maxheap后又立刻出堆,再取负号(3),添加入minheap,满足if语句,minheap中最小元素2出堆,取负号(-2),添加入maxheap中

addNum(2),self.minheap=[2,3],self.maxheap=[-2,-1]

过程分析:元素-num(-2),添加入maxheap后又立刻出堆,再取负号(2),添加入minheap,不满足if语句

计算中位数过程:

如果添加的元素为1,2,3:

if len(self.maxheap) > len(self.minheap):此句代码也起到判断元素奇数偶数的功能,maxheap的首位取负数,恰好是中位数。

如果添加的元素为1,2,3,2,-maxheap[0]与minheap[0]求平均,恰好是中位数。

参考:

https://blog.csdn.net/chandelierds/article/details/91357784 

http://www.voidcn.com/article/p-sbnrdexb-bvn.html

posted on 2020-12-26 12:16  Harukaze  阅读(190)  评论(0)    收藏  举报

导航