数据流中的中位数
有一个数据流一直输入字符,用insert方法插入数据,用另一个方法获得中位数。这个题的做法就是构建堆结构,一个为最小堆,一个为最大堆,因为数组的长度是变化的,所以直接用优先级队列吧。
插入之后保证最小堆的数全部大于最大堆,且两边数目不能相差超过1。所以如果现在个数为偶数,则下一个插入最大堆,那怎么保证此时插入的数据小于全部的最小堆呢,就是先把数据插入最小堆,返回堆顶之后再插入最大堆。如果此时个数为奇数,说明上一个一定插入的是最大堆,则现在要插入最小堆,怎么做和上面类似
获得中位数的时候就是如果个数为奇数返回最小堆堆顶,如果个数为偶数,则返回两个堆顶之和,注意这里返回的时候要先利用new Double变成double类型之后再除以2。
此时得到中位数的复杂度为O(1),插入复杂度为O(logn)
import java.util.PriorityQueue;
import java.util.Comparator;
public class Solution {
PriorityQueue<Integer> smallP=new PriorityQueue<Integer>((Integer a,Integer b)->{return a-b;});//其实默认就是小顶堆,试一下拉姆达表达式
PriorityQueue<Integer> bigP=new PriorityQueue<Integer>(new Comparator<Integer>(){
public int compare(Integer a,Integer b){
return b-a;
}
});
int count=0;
public void Insert(Integer num) {
if((count&1) ==1){
smallP.offer(num);
num=smallP.poll();
bigP.offer(num);
count++;
}else{
bigP.offer(num);
num=bigP.poll();
smallP.offer(num);
count++;
}
}
public Double GetMedian() {
if((count&1) ==1){//因为插的时候是如果为偶数则插到小顶堆,所以弹出也是小顶堆.
return new Double(smallP.peek());
}else{
return new Double(bigP.peek()+smallP.peek())/2;
}
}
}