Java中可用数组模拟单调队列解决滑动窗口最值问题,时间复杂度O(n);核心是用下标数组+head/tail指针维护单调性与窗口有效性,入队弹尾、出队查头、满窗记录结果。

在 Java 中,可以用数组模拟单调队列(Monotonic Queue)来高效解决滑动窗口最大值/最小值问题,时间复杂度稳定为 O(n),远优于暴力的 O(nk)。核心在于维护一个“下标数组”,使其对应元素值严格单调递增(求最小值)或严格单调递减(求最大值),同时保证下标在当前窗口内。
单调队列的数组结构设计
不使用 Deque 类,而是用一个普通整型数组 deque 存储原数组的下标(不是元素值),配合两个指针 head 和 tail 模拟双端队列:
-
deque[head]是当前窗口内最值对应的下标(队首) -
deque[head...tail-1]存储有效下标,满足对应元素单调(如递减) - 初始化时
head = tail = 0;入队在tail端,出队在head端
维护单调性:入队时从尾部弹出
每次新下标 i 入队前,从 tail-1 往前检查:
- 若求最大值,且
nums[deque[tail-1]] ,说明它不可能再成为后续窗口最值,tail--弹出 - 重复直到队尾元素 >
nums[i]或队空,再将i写入deque[tail++] - 若求最小值,则改为
>=判断,保持队列元素值递增
保证窗口有效性:出队时检查下标越界
窗口左边界是 i - k + 1,每次处理位置 i 前需清理过期下标:
- 若
deque[head] ,说明队首下标已滑出窗口,执行head++ - 该判断应在获取当前窗口最值前进行(即每轮循环开头或结尾统一处理)
- 只有当
i >= k - 1(即窗口已填满)时,才记录nums[deque[head]]为答案
完整示例:滑动窗口最大值(数组实现)
以下为简洁可运行逻辑(省略输入输出,聚焦核心):
int[] maxSlidingWindow(int[] nums, int k) {
int n = nums.length;
int[] res = new int[n - k + 1];
int[] deque = new int[n]; // 下标容器
int head = 0, tail = 0;
<pre class="brush:java;toolbar:false;">for (int i = 0; i = k - 1) {
res[i - k + 1] = nums[deque[head]];
}
}
return res;
}
注意:数组 deque 容量设为 n 足够(最多存 k 个下标,但安全起见用 n);所有操作均为 O(1) 均摊,整体线性。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











