子串----2.滑动窗口最大值

利用双端队列作为窗口

        添加元素前 先删除所有比自己小的元素 再将自己添加在队尾  保证单调性

        队列中存放元素的索引 而不是直接存元素 便于通过索引判断何时淘汰队首

class Solution {
    public int[] maxSlidingWindow(int[] nums, int k) {
        //利用双端队列作为窗口
        //添加元素前 先删除所有比自己小的元素 再将自己添加在队尾  保证单调性
        //队列中存放元素的索引 而不是直接存元素 便于通过索引判断何时淘汰队首

        int len = nums.length;
        int[] maxWnd = new int[len - k + 1]; //记录每个窗口的最大值

        //双端队列 便于操作队首与队尾
        Deque<Integer> wnd = new ArrayDeque<>();

        for(int i = 0 ; i < len; i++) {
            //添加元素到队列中 若即将加入的元素 更大 则删除前一个元素 直到即将添加的元素不是最大或队列已清空 清空则说明当前元素是历史最大值
            //移除较小的值 将更大的值添加在队首 保证单调性
            while(!wnd.isEmpty() && nums[i] > nums[wnd.getLast()]) {
                wnd.removeLast();
            }
            //将当前元素添加到队尾
            //经过第一步的特殊处理后 可以保证单调性 要么紧邻比自己大的元素 要么是历史最大值清空了队列队尾即队首
            wnd.addLast(i);

            //出队 若队首元素已不在窗口中 则移除
            if(i - wnd.getFirst() >= k) {
                wnd.removeFirst();
            }

            //记录当前窗口的最大值 
            if(i >= k - 1) { //由于未进行初始化 第一个窗口成型才添加最大值
                maxWnd[i - k + 1] = nums[wnd.getFirst()];
            }
        }
        return maxWnd;

    }
        
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值