leetcode239.滑动窗口最大值

通过单调队列实现LeetCode 239题的滑动窗口最大值问题。重点在于理解单调队列的工作原理,如何在窗口中正确地进行元素的弹出和插入,保持队列头部始终为当前窗口的最大值。代码实现时,注意处理特殊情况,如数组长度为1的情况,以确保算法的正确性和效率。
摘要由CSDN通过智能技术生成

https://leetcode-cn.com/problems/sliding-window-maximum/

用单调队列来做,学习到了单调队列!终于遇到hard了,原来都是套路

class Solution {
    public int[] maxSlidingWindow(int[] nums, int k) {
        MyQueue myQueue = new MyQueue();
        if(nums.length == 1) return nums;
        int[] res = new int[nums.length - k + 1];
        
        int j = 0;
        for(int i = 0;i < k;i++){
            myQueue.push(nums[i]);
        }
        res[j++] = myQueue.front();

        for(int i = 1; i < nums.length - k + 1;i++){
            myQueue.pop(nums[i - 1]);
            myQueue.push(nums[i + k - 1]);
            res[j++] = myQueue.front();
        }
        return res;
    }
}

class MyQueue{
    Deque<Integer> queue = new LinkedList<>();
    
    void pop(int val){
        if(val == queue.getFirst() && !queue.isEmpty()){
            queue.pollFirst();
        }
    }

    void push(int val){
        while(!queue.isEmpty() && val > queue.getLast()){
            queue.pollLast();
        }
        queue.addLast(val);
    }
    int front(){
        return queue.getFirst();
    }
}

思路:

1.先自己构建单调队列,滑动窗口的pop和push函数。

2.pop函数,如果要pop的val等于最大值(队列头),就pop掉,如果不是,就不修改队列

3.push函数,如果要push的val比队列尾巴大,就把尾巴去掉,直到val等于或者小于,又或者队列空了,再push这个val,保证队列中的头永远是滑动窗口中的最大值。

4.主函数思路,先构建滑动窗口,特殊处理第一个最大值,后续用for循环操作,注意数组下标的问题,特判nums.length == 1的情况即可。


class Solution {
    public int[] maxSlidingWindow(int[] nums, int k) {
        Deque<Integer> queue = new LinkedList<>();
        if(nums.length == 1) return nums;
        int[] res = new int[nums.length - k + 1];
        int front,later;
        int j = 0;
        for(int i = 0;i < k;i++){
            while(!queue.isEmpty() && nums[i] > queue.getLast()){
                queue.pollLast();
            }
            queue.addLast(nums[i]);
        }
        res[j++] = queue.getFirst();

        for(int i = 1; i < nums.length - k + 1;i++){
            later = nums[i - 1];
            front = nums[i + k - 1];
            if(!queue.isEmpty() && later == queue.getFirst()) queue.pollFirst();
            while(!queue.isEmpty() && front > queue.getLast()){
                queue.pollLast();
            }
            queue.addLast(front);
            res[j++] = queue.getFirst();
        }
        return res;
    }
}

直接把单调队列写进主函数里,运行速度快了不少诶,代码可读性还是前者好,运行速度是后者快

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值