面试题64:数据流中的中位数

来源:互联网 发布:免费的经济数据库软件 编辑:程序博客网 时间:2024/04/19 08:30
思路:
为了保证插入新数据和取中位数的时间效率都高效,这里使用大顶堆+小顶堆的容器,并且满足:
1、两个堆中的数据数目差不能超过1,这样可以使中位数只会出现在两个堆的交接处;
2、大顶堆的所有数据都小于小顶堆,这样就满足了排序要求。


核心思路:
            1.维护一个大顶堆,一个小顶堆,且保证两点:
                1)小顶堆里的全大于 大顶堆里的;
                2)2个堆个数的差值小于等于1
            2.当insert的数字个数为奇数时:使小顶堆个数比大顶堆多1;
              当insert的数字个数为偶数时,使大顶堆个数跟小顶堆个数一样。
            3.那么当总数字个数为奇数时,中位数就是小顶堆堆头;
                  当总数字个数为偶数时,中卫数就是 2个堆堆头平均数


import java.util.*;public class Solution {                                                                     private PriorityQueue<Integer> min = new PriorityQueue<>();    private PriorityQueue<Integer> max = new PriorityQueue<>(11, new Comparator<Integer>() {        @Override        public int compare(Integer o1, Integer o2) {            //PriorityQueue默认是小顶堆,实现大顶堆,需要反转默认排序器            return o2 - o1;        }    });    public void Insert(Integer num) {        if(((min.size()+max.size())&1)==0){                        if(max.size()>0 && num<max.peek()){                max.offer(num);                num=max.poll();            }            min.offer(num);        }else{            if(min.size()>0&&min.peek()<num){                min.offer(num);                num=min.poll();            }            max.offer(num);        }    }    public Double GetMedian() {        int size=min.size()+max.size();        if((size&1)==1) // 判断奇数的高效写法            return (double)min.peek();  //总数为偶数时,小顶堆堆顶就是中位数        else            return (((double)min.peek()+max.peek())/2.0);    }}


阅读全文
0 0
原创粉丝点击