题目
牛客网链接
持续输入数据,数据均为正,每输入一个数据,输出所有已输入数据的中位数
数据总数为奇数则输出最中间的数,为偶数则输出最中间两数平均值
思路
维护两个堆:
大根堆maxHeap
,保存较小的一半数
小根堆minHeap
,保存较大的一半数
当有一个新数字输入,为了保持两个堆分别保存一半数量的元素:
- 若两堆元素个数相等,加入大根堆
- 若上次加入了大根堆,则本次加入小根堆
每次加入新元素后,检查大顶堆顶元素是否大于小顶堆顶元素,若是则交换两个堆顶元素
实现
heapq实现小顶堆,大顶堆
python中heapq
模块可以将列表转化为堆,默认为小顶堆
;若要实现大顶堆
,可以在插入元素时取相反数,即可用小顶堆模拟大顶堆
heappushpop和heappush实现本题中交换堆顶元素操作
每次加入新元素后,检查大顶堆顶元素是否大于小顶堆顶元素,若是则交换两个堆顶元素
heappush
:将列表作为小根堆,插入元素并调整heappushpop
:向堆中插入元素并调整,再弹出堆顶元素
向堆A
插入元素之前,使用heappushpop
,将元素先插入另一个堆B
,再取B
堆顶元素,插入A
,即可实现
代码
from heapq import heappush,heappushpop
class Solution:
def __init__(self):
# 维护一个大顶堆和一个小顶堆
# heapq使用的是小顶堆,要实现大顶堆,在加入元素时给元素取反
self.maxHeap = []
self.minHeap = []
def Insert(self, num):
# 当有新元素插入,优先加入大顶堆;若大顶堆顶元素比小顶堆顶大则交换
if len(self.maxHeap) == len(self.minHeap):
heappush(self.maxHeap, -heappushpop(self.minHeap,num))
# 上次加入了大顶堆,本次加入小顶堆
else:
heappush(self.minHeap, -heappushpop(self.maxHeap,-num))
def GetMedian(self):
# 两个堆元素个数相等,返回两个堆顶平均值
if len(self.maxHeap) == len(self.minHeap):
return (self.minHeap[0] - self.maxHeap[0]) / 2
# 大顶堆元素多,返回大顶堆顶
else:
return -self.maxHeap[0]
参考链接
https://blog.csdn.net/u010770184/article/details/53349152
https://blog.csdn.net/qq_45880043/article/details/119039260