leetcode-困难题-239. 滑动窗口最大值(队列的应用)

队列的操作可以参考一下篇,它在Linkedlist类里面已经有实现。
https://blog.csdn.net/Fly_as_tadpole/article/details/86536539
主要就是和栈的push.pop一类的方法区分开,它的入列方法是offer,出列方法是poll。
题目链接
这道题目的方法比较难,需要使用到一个双向队列,解决办法如下:

https://leetcode-cn.com/problems/sliding-window-maximum/solution/shuang-xiang-dui-lie-jie-jue-hua-dong-chuang-kou-2/

这个方法当中我提出了一些难点的理解:

  1. 这个队列为什么和队尾比较?
    因为队尾是最新加入进去的,依次向队头变久
  2. 为什么不在范围内要队头pop?
    因为队头表示滑动窗口内最大的数。
    如果他不在范围了,当然要弹出来了。
伪代码:
class Solution {
    public int[] maxSlidingWindow(int[] nums, int k) {
        Queue<Integer> queue = new LinkedList<>();
        for(int i = 0; i < nums.length; i++){
            //前三个,不用添加到res
            if(queue空的)
            入列;continueif(queue非空){
                while(queue非空 && 队尾的数 < 右指针那个数){
                    队尾出列;
                }
                入列;
                while(队头的数下标在窗口外){
                    出列;
                }
                res.add(队头的数)}
        }
        return res;
    }
}

改出来的代码:(居然做出来了一道hard,喜极而泣,到头而睡)

class Solution {
    public int[] maxSlidingWindow(int[] nums, int k) {
        LinkedList<Integer> queue = new LinkedList();
        int[] res = new int[nums.length-k+1];
        if(nums.length<2)return nums;
        for(int i = 0; i < nums.length; i++){
            if(queue.peek() == null){
               queue.add(i);//入列
            }
            
            if(queue.peek() != null){
                //与队尾数比较,并顶到最前
                while(queue.peek() != null && nums[queue.peekLast()] <= nums[i]){
                    queue.pollLast();
                }
                queue.add(i);//入列
                //队头不在窗口就出列
                while(queue.getFirst() < i-k+1){
                    queue.pollFirst();
                }
                if(i >= k - 1)//前k个,不用添加到res
                res[i-k+1]= nums[queue.getFirst()];
            }
        }
        return res;
    }
}

你可能感兴趣的:(算法,leetcode,算法,职场和发展)