找滑动窗口的中位数

原文地址

找滑动窗口的中位数,主要思想利用堆,一个左边大顶堆,右边小顶堆,中间中位数。滑动窗口的过程中,添加新元素,删除不在窗口范围的老元素,并且调节两个堆的size保持平衡。

public class Solution {  
    public class minComparator implements Comparator<Integer> {  
        public int compare(Integer a, Integer b){  
            if(a > b) return 1;  
            else if(a == b) return 0;  
            else return -1;  
        }  
    }  
    public class maxComparator implements Comparator<Integer> {  
         public int compare(Integer a, Integer b){  
            if(a > b) return -1;  
            else if(a == b) return 0;  
            else return 1;  
        }  
    }  
    /** 
     * @param nums: A list of integers. 
     * @return: The median of the element inside the window at each moving. 
     */  
    public ArrayList<Integer> medianSlidingWindow(int[] nums, int k) {  
        // write your code here  
        ArrayList<Integer> res = new ArrayList<Integer>();  
        if(nums.length < k || k <= 0) {  
            return res;  
        }  
          
        PriorityQueue<Integer> minHeap = new PriorityQueue<Integer> (k, new minComparator());  
        PriorityQueue<Integer> maxHeap = new PriorityQueue<Integer> (k, new maxComparator());  
          
        int median = nums[0];  
        for(int i = 1; i < k; i++){  
            if(nums[i] < median) {  
                maxHeap.offer(nums[i]);  
            }  
            else {  
                minHeap.offer(nums[i]);  
            }  
            if(maxHeap.size() > minHeap.size()){  
                minHeap.offer(median);  
                median = maxHeap.poll();  
            }  
            if(maxHeap.size() < minHeap.size()-1){  
                maxHeap.offer(median);  
                median = minHeap.poll();  
            }  
        }  
        res.add(median);  
          
        for(int i = k ; i < nums.length; i++){  
            // add new one  
            if(nums[i] < median) {  
                maxHeap.offer(nums[i]);  
            }  
            else {  
                minHeap.offer(nums[i]);  
            }  
  
            // remove the old out of heaps  
            int old = nums[i-k];  
            if(old == median) {  
                if(minHeap.size() > maxHeap.size()){  
                    median = minHeap.poll();  
                }  
                else {  
                    median = maxHeap.poll();  
                }  
            }  
            else if(old < median) {  
                maxHeap.remove(old);  
            }  
            else {  
                minHeap.remove(old);  
            }  
              
            while(maxHeap.size() > minHeap.size()){  
                minHeap.offer(median);  
                median = maxHeap.poll();  
            }  
            while(maxHeap.size() < (minHeap.size()-1)){  
                maxHeap.offer(median);  
                median = minHeap.poll();  
            }  
              
            res.add(median);  
        }  
          
        return res;  
    }  
}  
  
  
  
/  
对于数组 [1,2,7,8,5], 滑动大小 k = 3 的窗口时,返回 [2,7,7]  
  
最初,窗口的数组是这样的:  
  
[ | 1,2,7 | ,8,5] , 返回中位数 2;  
  
接着,窗口继续向前滑动一次。  
  
[1, | 2,7,8 | ,5], 返回中位数 7;  
  
接着,窗口继续向前滑动一次。  
  
[1,2, | 7,8,5 | ], 返回中位数 7;  

 

转载于:https://www.cnblogs.com/gaofei-1/p/7474009.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值