当前位置:首页 > 未命名 > 正文内容

【解题报告】【lintcode81】Data Stream Median

u3blog8年前 (2016-05-19)未命名199

题意

给出一组数字,逐一输入,每输入一个数字,就输出已经输入数字排序后的中位数,即中间那个数字

解答

直接暴力很简单,但是时间复杂度很高,不符合性能要求。 时间复杂度要求是nlogn,可以想到的是快速排序和堆排序两种排序,再结合题目,我们选择堆 维护两个堆,一个堆比中位数小,一个比中位数大,我们称之为大堆,小堆 大堆是一个比中位数大的小根堆,堆顶是刚刚比中位数大的数 小堆是一个比中位数小的大根堆,堆顶是刚刚比中位数小的数 每次获得一个数的时候,先与目前的中位数比较,大就加入大堆,小就加入小堆,如果加入完毕之后两个堆的大小不一致了,就应该重新查找中位数了 1.如果大根堆比小根堆大,先把中位数放入小堆,再从大堆拿出堆顶 2.如果小堆比大堆大,同上 由于对堆的维护时间复杂度是logn满足了我们的需求 这样,我们就能每次logn的复杂度拿到中位数了

代码

public class Solution {
    /**
     * @param nums: A list of integers.
     * @return: the median of numbers
     */
  public int[] medianII(int[] nums) {
        // write your code here
         Comparator<Integer> cmp = new Comparator<Integer>() {
            @Override
            public int compare(Integer o1, Integer o2) {
                return o2-o1;
            }
        };
        PriorityQueue<Integer> maxQueue = new PriorityQueue<Integer>(20,cmp);
        PriorityQueue<Integer> minQueue = new PriorityQueue<Integer>(20,cmp);
        
        int median;
        int[] medians;
        if (nums == null ||nums.length == 0)
            return new int[]{};
        medians = new int[nums.length];
        median = nums[0];
        medians[0] = median;
        for(int i = 1;i < nums.length;i++){
            if (nums[i] < median){
                maxQueue.add(nums[i]);
            }else{
                minQueue.add(-1*nums[i]);
            }
            if (maxQueue.size() > minQueue.size()){
                 minQueue.add(-1*median);
                 median = maxQueue.poll();
            }else if (maxQueue.size() +1<minQueue.size()){
                maxQueue.add(median);
                median = -1*minQueue.poll();
            }
            medians[i] = median;
        }
        return medians;
    }
}

扫描二维码推送至手机访问。

版权声明:本文由u3blog发布,如需转载请注明出处。

本文链接:https://u3blog.xyz/?id=424

分享给朋友:

发表评论

访客

◎欢迎参与讨论,请在这里发表您的看法和观点。