题目描述
给你一个整数数组 nums,有一个大小为 k 的滑动窗口从数组的最左侧移动到数组的最右侧。你只可以看到在滑动窗口内的 k 个数字。滑动窗口每次只向右移动一位。
返回滑动窗口中的最大值。
图片说明

运行结果
图片说明
思路总结
之前牛客上是采用双指针加大顶堆实现的。但是会出现超时,无法通过
题解的思路是采用双端队列的方式(思想和实现一个求最大值的队列的时间为O(1)是一样的)
1.维持一个单调序列:即维持一个序列满足单调。(队列里存的是一个滑动窗口的情况)
入队规则:如果要加入的元素比队尾元素大,则移除队尾元素,直到小于队尾元素时,将该元素入队
出队规则:队头一直是当前队列的最大值。---当窗口右移时,如果窗口前移出的值和队头元素一致,则移除队头
最后滑动窗口的最大值一定是队头元素,直接入队即可

import java.util.*;
class Solution {
    //双指针加大顶堆---超时
    /*public int[] maxSlidingWindow(int[] nums, int k) {
        int[] ans=new int[nums.length-k+1];
        if(k <=0 || k > nums.length) return ans;
        PriorityQueue<Integer> max_heap=new PriorityQueue<Integer>(new Comparator<Integer>(){
            @Override
            public int compare(Integer o1,Integer o2){
                return o2-o1;
            }
        }); 
        for(int i=0,j=k;j<=nums.length;i++,j++){
            for(int m=i;m<j;m++){
                max_heap.offer(nums[m]);
            }
            ans[i]=max_heap.peek();
            max_heap.clear();
        }
        return ans;
    }*/
    //求最大值时间为O(1)的队列
    public int[] maxSlidingWindow(int[] nums, int k) {
        int len = nums.length;
        if (len == 0) {
            return nums;
        }
        int[] ans = new int[len - k + 1];
        int ans_index = 0;
        //我们需要维护一个单调递增的双向队列
        Deque<Integer> deque = new LinkedList<>();
        //先将第一个窗口的值按照规则入队
        for (int i = 0; i < k; i++) {
            while (!deque.isEmpty() && deque.peekLast() < nums[i]) {
               deque.removeLast();
            }
            deque.offerLast(nums[i]);
        }
        //存到数组里,队头元素
        ans[ans_index++] = deque.peekFirst();
        //移动窗口
        for (int j = k; j < len; j++) {
            //对应咱们的红色情况,则是窗口的前一个元素等于队头元素
            if (nums[j - k] == deque.peekFirst()) {
                deque.removeFirst();
            }
            while (!deque.isEmpty() && deque.peekLast() < nums[j]) {
                deque.removeLast();
            }
            deque.offerLast(nums[j]);
            ans[ans_index++] = deque.peekFirst();
        }
        return ans;
    }
}