栈和队列-滑动窗口最大值

代码随想录-刷题笔记

239. 滑动窗口最大值 - 力扣(LeetCode)

内容:

这道题给我的收获真的很大,主要是学会了一个新的数据结构。

单调队列:

单调-从名字就可以知道,要么单调递增,要么单调递减。 

单调队列是从队首开始递减的一个队列,并且一定是单调递减

队首应该是第一大,依次是第二大,第三大 .... 

针对滑动窗口,无非是进行遍历,使用双指针, 一个为start , 一个为 end 

二者分别代表窗口的起点和终点,距离是k 每次要进行的是 nums[end]入队, nums[start]出队 . 

滑动窗口问题解决了,每次我们获取队列当中的最大值不就解决问题了吗 . 

获取最大值,需要请出我们的 单调队列

单调队列也有问题,就是无法保证队列的完整信息, 只能保证最大值一定存在, 这不是完美的切合我们的问题了嘛!

下面的代码注释部分给出单调队列的详解

代码如下:

class Solution {
    public class MyQueue{
        //使用双端队列,该数据结构更适合实现单调队列,因为单调队列每次要跟队尾进行比较,如果比队尾大,那么队尾需要出队.
        public Deque<Integer> queue = new LinkedList<>(); 
        public void pop(int val) {
           
            if(!queue.isEmpty() && queue.peekFirst() == val) {
                queue.removeFirst();
            }
        }
        public void push(int val) {
            //跟队尾比较
            while(!queue.isEmpty() && val > queue.peekLast()) {
                queue.removeLast();
            }
            queue.addLast(val);
        }
        public int front(){
            return queue.peekFirst();
        }
    }
    public int[] maxSlidingWindow(int[] nums, int k) {
        List<Integer> result = new ArrayList<>();
        MyQueue queue = new MyQueue();
        for(int i = 0 ; i < k  ; i++) {
            queue.push(nums[i]);
        }
        result.add(queue.front());
        //遍历即可,实际上end-k暗含另外一个start指针~
        for(int end = k  ; end < nums.length ; end++) {
            queue.push(nums[end]);
            queue.pop(nums[end-k]);
            result.add(queue.front());
        }
        return result.stream().mapToInt(Integer::intValue).toArray();
    }
}

总结:

单调队列,单调栈,对于解决特化问题有奇效!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值