241016-239滑动窗口最大值

40 阅读1分钟

给你一个整数数组 nums,有一个大小为 k **的滑动窗口从数组的最左侧移动到数组的最右侧。你只可以看到在滑动窗口内的 k 个数字。滑动窗口每次只向右移动一位。

返回 滑动窗口中的最大值

示例 1:

输入: nums = [1,3,-1,-3,5,3,6,7], k = 3
输出: [3,3,5,5,6,7]
解释:
滑动窗口的位置                最大值
public int[] maxSlidingWindow(int[] nums, int k){
    //如果还是用hash存储,然后按固定窗口滑动,因为nums[i]可能达到10^4,感觉额外空间复杂度太高
    //求局部最值,想到了单调栈,又因为要pop先进去的元素————转为维护单调队列
    //维护一个非递增的单调队列,如果滑动pop的是头部位置,下一个头部元素仍然是当前最大值

    //固定的滑动窗口,一增一减
    ArrayDeque<Integer> queue = new ArrayDeque<>();
    //初始化
    int[] res = new int[nums.length - k + 1];
    for (int i = 0; i < k; i++) {
        //重复元素不丢弃,这样
        while (!queue.isEmpty() && queue.getLast() < nums[i]){
            queue.removeLast();
        }
        queue.addLast(nums[i]);
    }
    res[0] = queue.getFirst();

    for (int i = k; i < nums.length; i++) {
        int first = queue.getFirst();
        int pop = nums[i - k];
        if (first == pop){
            queue.removeFirst();
        }
        //加入新的一个元素到单调队列
        while (!queue.isEmpty() && queue.getLast() < nums[i]){
            queue.removeLast();
        }
        queue.addLast(nums[i]);
        res[i - k + 1] = queue.getFirst();
    }
    return res;
}