239. 滑动窗口最大值

239. 滑动窗口最大值

 单调队列思路:

0. 队列存储的是元素下标

1. 遍历数组元素

2. 维护队列:

队列不为空并且当前遍历元素 >= 队尾元素,向前压,比它小的全部被压扁了(删除了),直至队列为空或者遇到比它大的元素,停止。

4. 该元素下标入队

5. 计算窗口左边界left

6. 判断队首元素是否需要维护,如果 队首元素的下标  <  left 说明该元素已经不在窗口内,可以从队列中清除

7. 将窗口内的最大值存入数组(这里窗口内的最大值也即是队首元素)

8. 返回操作1,直至退出循环

class Solution {
    public int[] maxSlidingWindow(int[] nums, int k) {

        int[] res = new int[nums.length - k + 1];  // 窗口个数,存结果
        LinkedList<Integer> queue = new LinkedList<>(); // 单调队列,存元素下标

        // 遍历,right表示滑动窗口右边界
        for(int right = 0; right < nums.length; right++) {
            
            // 如果队列不为空且当前考察元素大于等于队尾元素,则移除队尾元素。
            // 直到,队列为空或当前考察元素小于新的队尾元素
            while (!queue.isEmpty() && nums[right] >= nums[queue.peekLast()]) {
                queue.removeLast();
            }

            // 元素下标入队
            queue.addLast(right);

            // 计算窗口左边界
            int left = right - k +1;

            // 当队首元素的下标 < 窗口左边界left:
            // 表示队首元素已经不再滑动窗口内,不用维护该元素,将其从队首移除
            if (queue.peekFirst() < left) {
                queue.removeFirst();
            }

            // 判断窗口是否形成。当 right + 1 >= k时,窗口形成
            // 此时,队首元素为 该窗口内 最大值
            if (right +1 >= k) {
                res[left] = nums[queue.peekFirst()];
            }
        }
        return res;
    }
}

 复杂度:

时间:O(n)

空间:O(k) 队列维护的窗口大小

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值