【第四周】滑动窗口的最大值

剑指 Offer 59 - I. 滑动窗口的最大值

239. 滑动窗口最大值

单调队列

双端队列保存有可能是滑动窗口最大值的数字的下标。
在存入一个数字的下标之前,先判断队列里已有数字是否小于待存入的数字,若是,则这些数字不可能是滑动窗口最大值,将它们依次从队尾删除。
此时,队头元素为滑动窗口最大值。
如果队头元素已经从窗口滑出,则将滑出的数字从队头删除。
因为队头和队尾都有可能删除数字,所以需要使用双端队列。
因为队列中元素满足严格单调递减,所以这种单调性的队列一般称作单调队列

class Solution {
    public int[] maxSlidingWindow(int[] nums, int k) {
        if(nums.length == 0 || k == 0) return new int[0];

        // 双端队列
        Deque<Integer> deque = new LinkedList<>();
        int[] res = new int[nums.length - k + 1];

        for (int i = 0; i < k; i++) {
            while (!deque.isEmpty() && nums[i] >= nums[deque.peekLast()]) {
                deque.pollLast();
            }
            deque.offerLast(i);
        }
        res[0] = nums[deque.peekFirst()];

        for (int i = k; i < nums.length; i++) {
            while (!deque.isEmpty() && nums[i] >= nums[deque.peekLast()]) {
                deque.pollLast();
            }
            if (!deque.isEmpty() && deque.peekFirst() <= i - k) {
                deque.pollFirst();          // 将窗口最左侧元素移出队列
            }
            deque.offerLast(i);         // 窗口向右移动一个位置,将新元素加入队列
            res[i - k + 1] = nums[deque.peekFirst()];
        }
        return res;
    }
}
  • 时间复杂度:O(n) ,n 是数组 nums 的长度,每一个下标恰好被放入队列一次,并且最多被弹出队列一次。
  • 空间复杂度:O(k) ,双端队列最多同时存储 k(窗口大小)个元素。
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容