首先看例子:https://leetcode-cn.com/problems/shu-ju-liu-zhong-de-zhong-wei-shu-lcof
解:
from heapq import * class MedianFinder: def __init__(self): # 大小堆一半一半,中位数只要取堆顶 但是python中的堆 堆的索引位置0的值是堆中的最小值 【B | A】 """ 建立一个 小顶堆 A 和 大顶堆 B ,各保存列表的一半元素,且规定: A 保存 较大 的一半,长度为 frac{N}{2}( N 为偶数)或 frac{N+1}{2} ( N 为奇数); B 保存 较小 的一半,长度为 frac{N}{2}( N 为偶数)或 frac{N-1}{2} ( N 为奇数); 随后,中位数可仅根据 A, B的堆顶元素计算得到。 """ self.A = [] #小顶堆 堆顶为最小值 self.B = [] #大顶堆 堆顶为最大值(所以实现起来 用 负数) def addNum(self, num: int) -> None: if len(self.A)!=len(self.B): heappush(self.A,num) heappush(self.B,-heappop(self.A)) else: heappush(self.B,-num) heappush(self.A,-heappop(self.B)) def findMedian(self) -> float: return self.A[0] if len(self.A) != len(self.B) else (self.A[0] - self.B[0]) / 2.0
heap
文档:heapq --- 堆队列算法 — Python 3.10.0 文档
- 只能是列表
- 能通过"<"比较
- 堆特性
一个列表heap它里面的每一个元素都符合 heap[0] <= heap[2*k+1]和heap[0] <= heap[2*k+2] ,那么这个heap就具有堆特性(python中的堆是最小堆, 也就是说堆的索引位置0的值是堆中的最小值.)
heapq.heappop(heap) 弹出索引位置0中的值
大佬:heapq.heappop(heap) 弹出索引位置0中的值 - 跟丫死磕 (weshallneversurrender.com)
heapq.heappush() 将一个对象压入堆中
大佬:python heapq.heappush() 将一个对象压入堆中 - 跟丫死磕 (weshallneversurrender.com)
C++中的大小堆用法解题
用库函数 priority_queue<int,vector<int>,less<int>> or priority_queue<int,vector<int>,greater<int>> 方便地实现大小堆:Priority Queue in C++ Standard Template Library (STL) - GeeksforGeeks
方法:
- res = minHeap.pop()
- minHeap.top()
- minHeap.push(item)
class MedianFinder { public: // 【左边 | 右边】 // 最大堆 堆顶为最大值 存储左边一半 priority_queue<int,vector<int>,less<int>> maxHeap; // 最小堆 堆顶为最小值 存储右边一半 priority_queue<int,vector<int>,greater<int>> minHeap; MedianFinder() { } void addNum(int num) { if(maxHeap.size()!=minHeap.size()){ maxHeap.push(num); int top_of_maxHeap = maxHeap.top(); maxHeap.pop(); minHeap.push(top_of_maxHeap); }else{ minHeap.push(num); int top_of_minHeap = minHeap.top(); minHeap.pop(); maxHeap.push(top_of_minHeap); } } double findMedian() { if(maxHeap.size()!=minHeap.size()){ return maxHeap.top()*1.0; }else{ return (maxHeap.top()+minHeap.top())*1.0/2; } } };