今日题目(剑指Offer系列)
剑指 Offer 41. 数据流中的中位数
如何得到一个数据流中的中位数?如果从数据流中读出奇数个数值,那么中位数就是所有数值排序之后位于中间的数值。如果从数据流中读出偶数个数值,那么中位数就是所有数值排序之后中间两个数的平均值。 例如, [2,3,4] 的中位数是 3 [2,3] 的中位数是 (2 + 3) / 2 = 2.5 设计一个支持以下两种操作的数据结构: void addNum(int num) - 从数据流中添加一个整数到数据结构中。 double findMedian() - 返回目前所有元素的中位数。
示例:
示例 1: 输入: ["MedianFinder","addNum","addNum","findMedian","addNum","findMedian"] [[],[1],[2],[],[3],[]] 输出:[null,null,null,1.50000,null,2.00000] 示例 2: 输入: ["MedianFinder","addNum","findMedian","addNum","findMedian"] [[],[2],[],[3],[]] 输出:[null,null,2.00000,null,2.50000]
解题思路:
>这道题目就是返回一个数据结构的中位数 >可以采用一个自动排序的数据结构 >这里我们采用的是两个堆,一个是大顶堆,一个是小顶堆 >Java中有个优先队列,底层是使用堆实现的,我们可以借助它 >在Python中存在heapq >但是heapq中只是小顶堆,所以可以存储相反数伪造了大顶堆 >需要使用值得时候只需要再次取反即可
Python解法:
from heapq import * class MedianFinder: def __init__(self): """ initialize your data structure here. """ self.A=[] self.B=[] def addNum(self, num: int) -> None: if len(self.A)!=len(self.B): heappush(self.B,-heappushpop(self.A,num)) else: heappush(self.A,-heappushpop(self.B,-num)) def findMedian(self) -> float: return (self.A[0]-self.B[0])/2.0 if len(self.A)==len(self.B) else self.A[0]
Java解法:
class MedianFinder { Queue<Integer> q1,q2; /** initialize your data structure here. */ public MedianFinder() { q1=new PriorityQueue<Integer>(); q2=new PriorityQueue<Integer>((x,y)->(y-x)); } public void addNum(int num) { if(q1.size()!=q2.size()){ q1.add(num); q2.add(q1.poll()); }else{ q2.add(num); q1.add(q2.poll()); } } public double findMedian() { return q1.size()==q2.size() ? (q1.peek()+q2.peek())/2.0:q1.peek(); } }