废话不多说,喊一句号子鼓励自己:程序员永不失业,程序员走向架构!本篇Blog的主题是【单调队列】,使用【队列】这个基本的数据结构来实现,这个高频题的站点是:CodeTop,筛选条件为:目标公司+最近一年+出现频率排序,由高到低的去牛客TOP101去找,只有两个地方都出现过才做这道题(CodeTop本身汇聚了LeetCode的来源),确保刷的题都是高频要面试考的题。

名曲目标题后,附上题目链接,后期可以依据解题思路反复快速练习,题目按照题干的基本数据结构分类,且每个分类的第一篇必定是对基础数据结构的介绍。
还是一道经典应用题

对于每个滑动窗口,我们可以使用 O(k)的时间遍历其中的每一个元素,找出其中的最大值。对于长度为 n的数组nums 而言,窗口的数量为 n−k+1,因此该算法的时间复杂度为 O((n−k+1)k)=O(nk),会超出时间限制,因此我们需要进行一些优化。我们可以想到,对于两个相邻(只差了一个位置)的滑动窗口,它们共用着 k−1 个元素,而只有 1 个元素是变化的。我们可以根据这个特点进行优化
在上述滑动窗口形成及移动的过程中,我们注意到元素是从窗口的右侧进入的,然后由于窗口大小是固定的,因此多余的元素是从窗口左侧移除的。 一端进入,另一端移除,这不就是队列的性质吗?所以,该题目可以借助队列来求解
设置双端队列为单调递减队列
当窗口未形成时,每次拿新的元素与队尾元素比较,如果大于队尾元素,则原队尾元素从尾部出队
当窗口形成时,队首元素就是最大元素,将其从队列头部出队,并加入结果集
当窗口形成后并继续滑动时,队首元素也要从队列头部出队,下一个最大值结果将出现在下一个滑动窗口中
该题目的求解思路就清晰了,具体如下:
由此思路可以写代码了
给出代码实现基本档案
基本数据结构:数组
辅助数据结构:单调队列
算法:无
技巧:双指针、滑动窗口
其中数据结构、算法和技巧分别来自:
当然包括但不限于以上
import java.util.*;
public class Solution {
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
*
* @param num int整型一维数组
* @param size int整型
* @return int整型ArrayList
*/
public ArrayList<Integer> maxInWindows (int[] num, int size) {
// 1 如果数组为空或者size小于1则返回空集合
if (num.length < 1 || size < 1) {
return new ArrayList<Integer>();
}
// 2 定义结果集并及双端单调队列,双端队列存储元素下标
ArrayList<Integer> result = new ArrayList<Integer>();
LinkedList<Integer> singleQueue = new LinkedList<Integer>();
// 3 开启窗口滑动
for (int right = 0; right < num.length; right++) {
// 3-1 如果单调队列不为空且队尾元素小于当前值,则出队
while (!singleQueue.isEmpty() && num[singleQueue.peekLast()] <= num[right]) {
singleQueue.pollLast();
}
// 当前元素下标入队
singleQueue.offerLast(right);
// 3-2 计算队首元素左边界,因为窗口固定大小,所以right向右移动时,left也向右移动
int left = right - size + 1;
if (left > singleQueue.peekFirst()) {
// 如果当前队列中最大值的索引已不在窗口中,则弹出队列
singleQueue.pollFirst();
}
// 3-3 如果right + 1 >= size,则意味着窗口形成,则队首元素即为窗口最大值,首次窗口形成后此判断条件一直成立
if (right + 1 >= size) {
result.add(num[singleQueue.peekFirst()]);
}
}
return result;
}
}
因为单调队列不限制大小,所以每次获取最大值前要先进行判断,当前队首元素还在不在窗口内,不在窗口内要移出去,防止用例过不去

时间复杂度:
空间复杂度:
普通队列、单调队列、优先队列和双向队列都是队列数据结构,但它们在性质和用途上有一些区别:
普通队列(Normal Queue):
单调队列(Monotonic Queue):
优先队列(Priority Queue):
双向队列(Double-Ended Queue,Deque):
总结: