当前位置: 首页 > news >正文

单调队列算法详解(附 Java 实战代码)

目录

一、什么是单调队列?

二、核心规则(以滑动窗口最大值为例)

三、经典例题:滑动窗口最大值

题目描述

Java 完整代码

代码核心解释

四、扩展:滑动窗口最小值

五、单调队列适用场景

六、总结


一、什么是单调队列?

单调队列= 队列 + 队列内元素严格单调递增 / 递减,是一种双端队列(Deque)实现的特殊数据结构。

核心特性:

  1. 队列头部始终是当前窗口 / 区间的最优值(最大值 / 最小值)
  2. 队列尾部用于添加新元素,维护单调性
  3. 插入 / 删除操作均为O(1),整体处理数组时间复杂度O(n)

它的核心用途:解决滑动窗口最值问题(暴力法 O (n・k),单调队列优化到 O (n))。


二、核心规则(以滑动窗口最大值为例)

我们维护一个单调递减队列

  1. 入队:新元素从队尾入队,把所有比它小的元素全部弹出(这些元素不可能成为后续窗口的最大值),再加入新元素下标
  2. 出队:如果队首元素下标超出窗口左边界,从队首弹出
  3. 取值:窗口形成后,队首元素就是当前窗口最大值

三、经典例题:滑动窗口最大值

题目描述

给定数组nums,大小为k的滑动窗口从数组最左侧移到最右侧,返回每个窗口的最大值。

示例:输入:nums = [1,3,-1,-3,5,3,6,7],k = 3输出:[3,3,5,5,6,7]

Java 完整代码

import java.util.ArrayDeque; import java.util.Deque; public class MonotonicQueue { public int[] maxSlidingWindow(int[] nums, int k) { // 边界判断 if (nums == null || nums.length == 0 || k <= 0) { return new int[0]; } int n = nums.length; // 结果数组长度:n - k + 1 int[] res = new int[n - k + 1]; int index = 0; // 双端队列:存储元素下标(方便判断是否超出窗口) Deque<Integer> deque = new ArrayDeque<>(); for (int i = 0; i < n; i++) { // 规则1:队首元素超出窗口左边界,移除 // 窗口左边界 = i - k + 1,队首 < 左边界 则过期 while (!deque.isEmpty() && deque.peekFirst() < i - k + 1) { deque.pollFirst(); } // 规则2:维护单调递减队列 // 新元素 >= 队尾元素,队尾弹出(不可能成为最大值) while (!deque.isEmpty() && nums[i] >= nums[deque.peekLast()]) { deque.pollLast(); } // 加入当前元素下标 deque.offerLast(i); // 规则3:窗口形成后(i >= k-1),记录队首最大值 if (i >= k - 1) { res[index++] = nums[deque.peekFirst()]; } } return res; } // 测试 public static void main(String[] args) { MonotonicQueue mq = new MonotonicQueue(); int[] nums = {1,3,-1,-3,5,3,6,7}; int k = 3; int[] result = mq.maxSlidingWindow(nums, k); System.out.print("滑动窗口最大值:"); for (int num : result) { System.out.print(num + " "); } // 输出:3 3 5 5 6 7 } }

代码核心解释

  1. 队列存下标:方便判断元素是否超出窗口范围
  2. 维护递减:保证队首永远是当前窗口最大值
  3. 窗口形成条件i >= k-1,此时开始收集结果
  4. 时间复杂度:每个元素仅入队 / 出队一次,O (n)

四、扩展:滑动窗口最小值

只需修改维护规则,改为单调递增队列

// 维护单调递增队列(最小值) while (!deque.isEmpty() && nums[i] <= nums[deque.peekLast()]) { deque.pollLast(); }

五、单调队列适用场景

  1. 滑动窗口最值(最经典)
  2. 子数组区间最值问题
  3. 动态维护区间极值
  4. 优化 DP(单调队列优化 DP)

六、总结

  1. 本质:用双端队列维护单调序列,保证 O (1) 获取最值
  2. 核心操作:队首过期删除、队尾维护单调性、窗口形成取队首
  3. 优势:把 O (n・k) 暴力优化到 O (n)
  4. Java 实现:用ArrayDeque存下标,效率最高
http://www.jsqmd.com/news/884705/

相关文章:

  • 拒绝低价甩卖!2026 佛山爱马仕 LV 香奈儿包包回收门店实测 - 奢侈品回收测评
  • 低成本锂电池充放电与容量测试方案:IP2312与HW-586模块组合实践
  • 长期使用Taotoken聚合端点对于保障项目开发进度的稳定性价值
  • 纯硬件实现I2C协议:从逻辑门到传感器通信的深度实践
  • 2026天津高端奢品包包回收测评|添价收正规资质机构甄选与行业实测解析 - 薛定谔的梨花猫
  • 基于ESP8266与DS18B20构建本地Wi-Fi温度监测系统
  • 2026低空治理新需求下的平台供应商推荐:黑飞监测预警系统能力观察 - 品牌2025
  • 正点原子MiniFly飞控源码实战:从PID参数配置到定点悬停调试全流程
  • 双向塑料土工格栅如何进行施工?
  • 商城网站建设哪家便宜?低价也能做出优质商城? - FaiscoJeff
  • Iwara视频下载神器:2025终极指南,一键批量下载全攻略
  • 2026芜湖婚纱照精选榜单|真实测评不踩雷,安心拍好每一套 - charlieruizvin
  • 基于ISDN信令的来电语音播报系统:从原理到树莓派实现
  • Frida Android动态插桩实战:绕过SSL Pinning与加固App Hook
  • 数据说话:洛阳蒙娜丽莎4000㎡场地+底片全送,婚纱照选店该看什么 - charlieruizvin
  • 邢台企业采购储罐怕踩坑?优选洋阳玻璃钢,专业玻璃钢储罐厂家,期待与您合作! - 资讯纵览
  • 3大实战场景深度解析:Box64如何让ARM设备流畅运行x86_64程序
  • 2026 优选:沈阳实惠的玩具小商品直供 / 益智玩具 / 儿童玩具推荐盘点,优选沈阳宝赢玩具超市 - 资讯纵览
  • 如何3分钟掌握百度网盘高速下载技巧:Python直链获取完全指南
  • 半样本自助法:为机器学习CATE估计器构建置信区间的实用指南
  • 如何用Untrunc拯救损坏视频?2025年终极MP4修复工具完全指南
  • OpenClaw Browser Relay直接连接 AI 与Chrome浏览器
  • 深度解析MoviePilot企业微信消息推送的智能时段控制机制
  • 大模型集体“下海”赚钱:2026年AI生死战已打响,免费时代正式终结?
  • 2026青岛婚纱照婚纱摄影推荐|备婚必看测评,闭眼选不踩雷(1) - charlieruizvin
  • 如何高效实现Windows自动化鼠标点击:AutoClicker完整实战指南
  • 拆解互联网:通俗易懂的网络分层模型
  • ArcGIS Pro模型构建器新玩法:像写Python一样玩转‘如果...就...’,实现智能化的空间数据处理流水线
  • NPU跑LLM实战指南:KV Cache动态性如何突破硬件限制
  • 阻燃布|阻燃面料十大品牌 2026 权威盘点:不燃耐温成核心选型标准,新能源、消防、军工、冶金、建筑等行业选型指南 - 资讯纵览