双端队列解滑动窗口最大值的核心是维护单调递减的索引队列,队首始终为当前窗口最大值对应下标,支持两端高效增删,时间复杂度O(n)。

用双端队列(Deque)解滑动窗口最大值,核心是维护一个「单调递减的索引队列」——队首始终对应当前窗口的最大值,且所有操作均摊 O(1),整体时间复杂度稳定在 O(n)。
为什么选双端队列
普通队列只能从一端删、一端加,无法灵活处理两类关键操作:既要从队首剔除过期索引(窗口左边界移动),又要从队尾剔除失效的小值索引(保证单调性)。双端队列支持两端高效增删,天然适配滑动窗口的动态更新需求。
队列里存的是下标,不是数值
存下标才能同时判断两个关键信息:该元素是否还在当前窗口内(通过和 i − k + 1 比较),以及它对应的值是多少(nums[index])。这样避免了额外映射或重复查找。
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- 队列中索引对应的 nums 值必须严格单调递减(允许相等时按题目要求处理,通常用
<或<=) - 队首索引一定在当前窗口范围内,且其值是窗口最大值
- 队尾索引对应最小候选值,新元素加入时会清掉所有比它小的“无用”索引
每步操作逻辑清晰
遍历数组每个位置 i(0 起始),执行三件事:
-
清理过期索引:若队首索引
dq.front() <= i − k,说明它已滑出窗口左侧,dq.pop_front() -
清理弱候选索引:只要队尾索引对应的值
nums[dq.back()] <= nums[i],就dq.pop_back();重复直到队空或遇到更大值 -
加入当前索引:
dq.push_back(i) -
记录答案:当
i >= k − 1(即窗口首次完整形成),取nums[dq.front()]存入结果
常见易错点提醒
边界判断要严谨:
- 窗口大小 k 为 1 时,结果就是原数组;k 大于数组长度时,结果为空 —— 实际编码需提前校验
- 清理过期索引的条件写成
dq.front() < i − k + 1或<= i − k都可,但必须统一;推荐用<= i − k更直观(索引超出左边界) - 比较时用
<=还是<影响相同值的保留策略:用<=会清掉等于当前值的旧索引,确保队首是最靠右的最大值位置,更符合多数题意

















