480. Sliding Window Median

题目链接:https://leetcode.com/problems...

这题和那道Find Median from Data Stream比起来多加了个sliding window。那道题巧妙的用了两个heap来找到mean,还有道题是Slide Window Maximum,同样是slide window的题。还是用两个heap来做,remove这个操作复杂度用了logk。minHeap和maxHeap,maxHeap在保存较小的一半元素,minHeap保存较大的一半元素,0 <= minHeap.size() - maxHeap.size() <= 1,注意maxheap写的时候不能用a - b,因为可能overflow。

public class Solution {
    public double[] medianSlidingWindow(int[] nums, int k) {
        int n = nums.length;
        double[] result = new double[n - k + 1];
        maxHeap = new PriorityQueue<>(k/2 + 1, (a, b) -> b.compareTo(a));
        minHeap = new PriorityQueue<>(k/2 + 1);
        
        for(int i = 0; i < n; i++) {
            // delete the element beyond the window
            if(maxHeap.size() + minHeap.size() == k) slide(nums[i - k]);
            // add new element to the window
            add(nums[i]);
            if(i >= k - 1) {
                result[i - k + 1] = getMedian();
            }
        }
        
        return result;
    }
    
    PriorityQueue<Integer> minHeap;
    PriorityQueue<Integer> maxHeap;
    private void slide(int target) {
        if(minHeap.contains(target)) minHeap.remove(target);
        else maxHeap.remove(target);
    }
    
    private void add(int num) {
        maxHeap.add(num);
        minHeap.add(maxHeap.poll());
        if(maxHeap.size() + 1 < minHeap.size()) maxHeap.add(minHeap.poll());
    }
    
    private double getMedian() {
        // window size is even
        if(minHeap.size() == maxHeap.size()) return minHeap.peek()/2.0 + maxHeap.peek()/2.0;
        else return minHeap.peek();
    }
}

没想出来其他方法,参考discussion的解法:
https://discuss.leetcode.com/...


lulouch13
13 声望6 粉丝