[LeetCode] Sliding Window Median

Posted 自在时刻

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[LeetCode] Sliding Window Median相关的知识,希望对你有一定的参考价值。

题目

Median is the middle value in an ordered integer list. If the size of the list is even, there is no middle value. So the median is the mean of the two middle value.
Examples:
[2,3,4] , the median is 3
[2,3], the median is (2 + 3) / 2 = 2.5
Given an array nums, there is a sliding window of size k which is moving from the very left of the array to the very right. You can only see the k numbers in the window. Each time the sliding window moves right by one position. Your job is to output the median array for each window in the original array.
For example,
Given nums = [1,3,-1,-3,5,3,6,7], and k = 3.
Window position Median
————— —–
[1 3 -1] -3 5 3 6 7 1
1 [3 -1 -3] 5 3 6 7 -1
1 3 [-1 -3 5] 3 6 7 -1
1 3 -1 [-3 5 3] 6 7 3
1 3 -1 -3 [5 3 6] 7 5
1 3 -1 -3 5 [3 6 7] 6
Therefore, return the median sliding window as [1,-1,-1,3,5,6].

题解

这道题目同样是在数据流中求取中位数,关键在于利用最大堆和最小堆。对于输入的数据保持这样两个堆,一个最大堆maxHeap,一个最小堆minHeap,并有以下性质:1、同时maxHeap中所有的数小于等于minHeap中所有的数(这步操作可以通过先将输入放进minHeap,再从minHeap中取出来最小数放进maxHeap实现) 2、maxHeap中元素个数大于等于minHeap中元素个数,这个性质可以通过插入,删除数据后进行均衡来实现:

public class Solution 
    private Queue<Double> minHeap = new PriorityQueue<>();
    private Queue<Double> maxHeap = new PriorityQueue<>(new Comparator<Double>()
        @Override
        public int compare(Double o1, Double o2) 
            if (o1 > o2) return -1;
            else if (o1 < o2) return 1;
            else return 0;
        
    );
    public double[] medianSlidingWindow(int[] nums, int k) 
        int n = nums.length - k + 1;
        if (n <= 0) return new double[0];
        double[] result = new double[n];

        for (int i = 0; i <= nums.length; i++) 
            if (i >= k) 
                result[i - k] = getM();
                remove(nums[i - k]);
            
            if (i < nums.length)
                add(nums[i]);
        
        return result;
    
    private void add(int num)
        //保持最大堆中元素小于最小堆中元素
        minHeap.add((double)num);
        maxHeap.add(minHeap.poll());
        //元素数目均衡操作
        if (minHeap.size() > maxHeap.size()) maxHeap.add(minHeap.poll());
        if (maxHeap.size() - minHeap.size() > 1) minHeap.add(maxHeap.poll());
    

    private void remove(int num)
        double mid = getM();
        double n = (double) num;
        if (n <= mid) 
            maxHeap.remove(n);
         else 
            minHeap.remove(n);
        
        if (maxHeap.size() < minHeap.size()) maxHeap.add(minHeap.poll());
        if (maxHeap.size() - minHeap.size() > 1) minHeap.add(maxHeap.poll());
    

    private double getM() 
        if (maxHeap.isEmpty() && minHeap.isEmpty()) return 0;
        if (minHeap.size() == maxHeap.size()) return ((double)maxHeap.peek() + (double)minHeap.peek()) / 2.0;
        else return (double)maxHeap.peek();
    

以上是关于[LeetCode] Sliding Window Median的主要内容,如果未能解决你的问题,请参考以下文章

LeetCode-Sliding Window Maximum

[LeetCode] Sliding Window Median

[LeetCode] Sliding Window Median

Leetcode: Sliding Window Median

LeetCode 239. Sliding Window Maximum(滑动窗口最大值)

leetcode 239. Sliding Window Maximum