借鉴这个老哥的解题思想https://blog.nowcoder.net/n/1b4531b1265d4fe1b9e4ca31c3c66da1
这是我的实现方法
//想要取得中位数O(1)
//中位数怎么求?数据排好序后
//1.奇数下
//就是中间那个
//2.偶数下
//就是中间两个的平均值
//可以将这些数据看成左右两半,约定左边的数目容许比右边多1
//这下好了,奇数下,中位数就是max(left)
// 偶数下,中位数就是(max(left)+min(left))>>1
//什么结构能简单获取最值?堆,其中左边用大根堆,右边用小根堆
//巧妙的数据流动思想:
//插入一个数
// 1.左边为空或者小于max(left),直接插入左边
// 2.否则,插入右边
//如果此时右边size=左边size+1,就匀一个来左边
//如果此时左边size=右边size+2,就匀一个到右边
public double[] flowmedian (int[][] operations) {
MedianHolder holder = new MedianHolder();
ArrayList<Double> list = new ArrayList<>();
for(int[] opr:operations){
if(opr[0]==1){
holder.insert(opr[1]);
}else{
list.add(holder.findMedium());
}
}
double[] res = new double[list.size()];
for(int i = 0;i<list.size();i++){
res[i] = list.get(i);
}
return res;
}
public static class MedianHolder{
PriorityQueue<Integer> left = new PriorityQueue<>((o1, o2)->o2-o1);
PriorityQueue<Integer> right = new PriorityQueue<>();
public void insert(int a){
//插入
if(left.isEmpty()||a<=left.peek()){
left.add(a);
}else{
right.add(a);
}
//匀
if(right.size()==left.size()+1){
left.add(right.poll());
}else if(left.size()==right.size()+2){
right.add(left.poll());
}
}
public double findMedium(){
int n = left.size()+right.size();
if(n==0) return -1;
if((n&1)==0){//偶数
return (double)(left.peek()+right.peek())/2;
}else{
return (double)left.peek();
}
}
} 
京公网安备 11010502036488号