题解 | #数据流中的中位数#
数据流中的中位数
https://www.nowcoder.com/practice/9be0172896bd43948f8a32fb954e1be1
解题思路:
1、这道题的难点,一个是要读懂题的意思,现在懂了,well done~!
2、还可以,用堆把数组分成两半,这是我没有想到的!下次有意识用起来。
3、最后,insert的过程,是我没有注意到的,insert的num 是不确定大小的!!!,所以先统一入min堆后,再突出排列好的新元素,吐出到max堆,之后,偶数变基数个的时候,会导致max堆比min堆多一个,所以,做了重新平衡,这些都是为了最终取数据用的!
import java.util.*;
public class Solution {
// 最小堆,存右边较大值,方便获取最小值
PriorityQueue<Integer> max = new PriorityQueue<Integer>();
// 最大堆,存左边较小值,方便获取最大值
PriorityQueue<Integer> min = new PriorityQueue<>((o1, o2)->o2.compareTo(o1));
public void Insert(Integer num) {
min.offer(num); //新数不确定大小,所以先放到左边的最大堆排序
max.offer(min.poll()); //新增一个元素后,min大小+1了,同时把最新的最大值吐出,给到最大堆
if(min.size() < max.size()) { //偶数个变基数个的时候,会导致右边队列比左边大,所以,又要再吐出来平衡
min.offer(max.poll());
}
}
public Double GetMedian() {
if(min.size()> max.size()) {
return (double) min.peek(); //奇数个的时候是不用除2的
} else {
return (double) (max.peek()+min.peek())/2; //偶数个的时候要除2,不过注意点
//(max.peek()+min.peek())/2; 和
//((max.peek()+min.peek())/2) 结果不一样
// 多了一个括号,再转double会先被去掉小数部分
// 不加括号,就不会了!
}
}
}
