分析
这里观察示例,如果数据流为空取中位数返回值为-1
取一个有序序列的中位数,可以从中位数的位置将左右两部分看成是左边部分是一个大根堆,右边部分是一个小根堆,通过维持两个堆来获取中位数
1、如果大根堆和小根堆的大小相等,那么先把数加入小根堆,然后弹出小根堆的堆顶元素加入大根堆
2、如果大根堆和小根堆的大小不想等(大根堆比小根堆多一个),先把元素加入大根堆,然后弹出大根堆的元素加入小根堆
3、如果两个堆的大小相等,那么中位数就是两个堆顶元素相加除以2,如果不想等,中位数就是大根堆的堆顶元素。
import java.util.*;
public class Solution {
/**
* the medians
* @param operations int整型二维数组 ops
* @return double浮点型一维数组
*/
public double[] flowmedian (int[][] operations) {
//小根堆
PriorityQueue<Integer> smallHeap = new PriorityQueue<>();
//大根堆
PriorityQueue<Integer> bigHeap = new PriorityQueue<>(new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
return o2-o1;
}
});
List<Double> list = new ArrayList<>();
for(int[] operation: operations) {
int o = operation[0];
switch (o) {
//添加操作
case 1:
//获取添加的数据
int num = operation[1];
//如果大根堆与小根堆的大小相同,则先将数据添加到小根堆中,在从小根堆中弹出一个数添加到大根堆中
if(smallHeap.size() == bigHeap.size()) {
smallHeap.add(num);
bigHeap.add(smallHeap.poll());
} else {//如果不相等,直接添加到小根堆中
bigHeap.add(num);
smallHeap.add(bigHeap.poll());
}
break;
//获取中位数的操作
case 2:
if(bigHeap.size() == 0 && smallHeap.size() == 0) {
list.add(-1.0);
} else
if(bigHeap.size() == smallHeap.size()) {
list.add((bigHeap.peek() + smallHeap.peek()) / 2.0);
} else {
list.add(bigHeap.peek() * 1.0);
}
break;
}
}
double[] res = new double[list.size()];
int i = 0;
for (double d : list) {
res[i++] = d;
}
return res;
}
}