Problem
You are given an array of integers nums, there is a sliding window of size k which is moving from the very left of the array to the very right. You can only see the k numbers in the window. Each time the sliding window moves right by one position.
Return the max sliding window.
Example 1:
Input: nums = [1,3,-1,-3,5,3,6,7], k = 3
Output: [3,3,5,5,6,7]
Explanation:
Window position Max
--------------- -----
[1 3 -1] -3 5 3 6 7 3
1 [3 -1 -3] 5 3 6 7 3
1 3 [-1 -3 5] 3 6 7 5
1 3 -1 [-3 5 3] 6 7 5
1 3 -1 -3 [5 3 6] 7 6
1 3 -1 -3 5 [3 6 7] 7
Example 2:
Input: nums = [1], k = 1
Output: [1]
Solution
判断核心思路
- 滑动窗口,符合先进先出 FIFO,使用队列
- 单调递减队列:来维护维护当前的窗口中最大的数字
理解单调队列
:::info
Input: nums = [1,3,-1,-3,5,3,6,7], k = 3
使用这个队列,窗口大小为3
:::
- nums[0] = 1 进入队列,得到队列 【1】
- nums[1] = 2 进入队列
- 判断当前队列的getLast() = 1,小于当前进入队列的值,需要将 1 从队列中移除
- 因为 1 已经不可能是这个窗口中最大的数字,它已经不被需要了,毕竟窗口一直向右移动嘛
- 此时队列中的数字是 【3】
- 判断当前队列的getLast() = 1,小于当前进入队列的值,需要将 1 从队列中移除
- nums[2] = -1 进入队列
- 判断当前队列的getLast() = 3,大于当前进入队列的值,则直接将-1,加进队列
- 此时队列中的数字是 【3,-1】
- 这就是单调递减队列!
- 注意,此时窗口与大小已经是3了,那得到了第一个窗口的最大值,就是队列的头 = 3
- nums[3] = -3 进入队列
- 判断当前队列的getLast() = -1,大于当前进入队列的值,则直接将-3,加进队列,此时队列 = 【3, -1, -3】
- 同时移动窗口的左侧指针,需要把 nums[0] 从窗口中剔除
- 考虑到但其实num[0] = 1 并不在队列中 (判断它是都等于队列的getFirst()),所以可以直接忽略
- 此时第二个窗口的最大值就是队列的头=3
- nums[4] = 5 进入队列
- 循环判断当前队列的getLast() ,只要是小于 5 的元素都要被剔除,毕竟我们要维护一个单调递减的队列,所以【3,-1,-3】变成了【5】
- 然后剔除num[1],同样它已经不在队列里了,忽略
- 此时第二个窗口的最大值就是队列的头=5
- 一次类推,后面的逻辑是重复的,不再赘述