2025年- H67-Lc175--295.数据流中的中位数(小根堆,大根堆)--Java版
1.题目描述
2.思路
假设当前加入了:[1, 2, 3, 4, 5, 6],要分成两半:
queMin 存:[3, 2, 1] → 最大堆 → 堆顶是 3
queMax 存:[4, 5, 6] → 最小堆 → 堆顶是 4
中位数 = (3 + 4) / 2 = 3.5
3.代码实现
class MedianFinder {PriorityQueue<Integer> queMax;// 大根堆,保存较小一半(保存数组中的较小的数,但是堆顶是最大元素。)[3,2,1]PriorityQueue<Integer> queMin; // 小根堆,保存较大一半(保存数组中的较大的数,但是堆顶是最小元素。)[4,5,6]public MedianFinder() {queMax=new PriorityQueue<Integer>((a,b)->(b-a));queMin=new PriorityQueue<Integer>();//小根堆的排序按默认就是升序排序,(a,b)->(a-b)}public void addNum(int num) {if(queMax.isEmpty()||num<=queMax.peek()){//大根堆为空,当前的元素小于等于大根堆的堆顶元素queMax.offer(num);//当前元素入大根堆的队列if(queMin.size()+1<queMax.size()){//大根堆比小根堆多两个元素及以上//将大根堆的堆顶元素入小根堆的队列//大根堆[5,4,3,2,1],小根堆[6,7,8]//更新:大根堆[4,3,2,1],小根堆[5,6,7,8]queMin.offer(queMax.poll());}}else{queMin.offer(num);//大根堆[3,2,1],小根堆[6,7,8,9]//入队之后:大根堆[6,3,2,1],小根堆[7,8,9]if(queMin.size()>queMax.size()){queMax.offer(queMin.poll());}}}public double findMedian() {if(queMax.size()>queMin.size()){//看入队之后的值,也就是更新后的值return queMax.peek();}else{return (queMax.peek()+queMin.peek())/2.0; }}
}/*** Your MedianFinder object will be instantiated and called as such:* MedianFinder obj = new MedianFinder();* obj.addNum(num);* double param_2 = obj.findMedian();*/