0

0

如何在Java中实现双端队列_Deque接口与ArrayDeque的滑动窗口实战

P粉602998670

P粉602998670

发布时间:2026-03-13 11:05:31

|

737人浏览过

|

来源于php中文网

原创

ArrayDeque 比 LinkedList 更适合滑动窗口,因其头尾增删 O(1)、缓存友好、扩容可控;必须存索引而非值以判断越界,初始化需处理边界情况,避免冗余清空和错误遍历。

如何在java中实现双端队列_deque接口与arraydeque的滑动窗口实战

滑动窗口里为什么选 ArrayDeque 而不是 LinkedList

因为 ArrayDeque 在头尾增删都是 O(1) 且缓存友好,LinkedList 虽然也实现 Deque,但每次操作要新建节点、指针跳转,实际慢 2–3 倍,尤其在窗口频繁移动时更明显。

常见错误是看到“链表天然支持双端”就默认选 LinkedList,结果压测时 CPU 突增,其实是内存不连续导致的 cache miss 太多。

  • ArrayDeque 底层是循环数组,扩容时复制成本可控;LinkedList 每次 addFirst 都触发对象分配
  • 如果窗口大小固定且已知上限(比如最大 10^5),可初始化容量:new ArrayDeque(maxSize),避免多次扩容
  • 别用 ArrayList 手动模拟——头插 add(0, x) 是 O(n),直接卡死滑动窗口逻辑

ArrayDeque 存索引而不是元素值,这是关键

滑动窗口求最大/最小值时,队列里必须存下标(int),不是数值本身。否则无法判断某个值是否已滑出窗口边界。

典型场景:给定数组 nums 和窗口大小 k,求每个窗口最大值。若存值,当 nums[0] 被移出后,你根本不知道队首那个数对应哪个位置,也就无法安全弹出。

立即学习Java免费学习笔记(深入)”;

  • 入队前,从队尾往前踢掉所有 ≤ 当前元素的旧索引(维持单调递减)
  • 检查队首索引是否 (即是否已不在当前窗口),是则 <code>pollFirst()
  • 队首始终是当前窗口最大值的下标:nums[deque.peekFirst()]

容易被忽略的边界:空队列、单元素窗口、k=1

ArrayDeque 自身不会报错,但业务逻辑常在这里崩——比如没判空就调 peekFirst(),或 k > nums.length 时仍硬算。

错误现象:NullPointerException 或结果数组长度不对,调试时发现某轮循环没写入值。

  • 初始化时若 k == 0nums 为空,直接返回空结果,别进主循环
  • 窗口从下标 0 开始,但第一个完整窗口结束位置是 k - 1,所以有效结果从 i = k - 1 开始填
  • k == 1 时,队列每轮只存一个索引,pollFirst() 后立刻 offerLast(),别漏掉任何一次 offer

性能陷阱:别在循环里反复调 size() 判空

ArrayDeque.size() 是 O(1),这点没问题;但新手常写 while (!deque.isEmpty()) 配合 pollFirst() 来清空,这在滑动窗口中完全没必要,还拖慢逻辑。

真正该做的是“按需清理”:只在新元素入队前清理队尾无效项,只在取答案前检查队首是否越界。多一步无意义的清空,等于给每次迭代加冗余操作。

  • 避免写:while (deque.size() > k) deque.pollFirst(); —— 窗口大小靠下标判断,不是靠队列长度
  • 不要用 for (int x : deque) 遍历队列取值 —— 这会触发内部迭代器创建,且顺序未必是你想要的
  • 调试时想看内容?用 System.out.println(deque) 就行,它输出的是从头到尾的元素序列

事情说清了就结束

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

WorkBuddy
WorkBuddy

腾讯云推出的AI原生桌面智能体工作台

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
while的用法
while的用法

while的用法是“while 条件: 代码块”,条件是一个表达式,当条件为真时,执行代码块,然后再次判断条件是否为真,如果为真则继续执行代码块,直到条件为假为止。本专题为大家提供while相关的文章、下载、课程内容,供大家免费下载体验。

107

2023.09.25

string转int
string转int

在编程中,我们经常会遇到需要将字符串(str)转换为整数(int)的情况。这可能是因为我们需要对字符串进行数值计算,或者需要将用户输入的字符串转换为整数进行处理。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

1031

2023.08.02

int占多少字节
int占多少字节

int占4个字节,意味着一个int变量可以存储范围在-2,147,483,648到2,147,483,647之间的整数值,在某些情况下也可能是2个字节或8个字节,int是一种常用的数据类型,用于表示整数,需要根据具体情况选择合适的数据类型,以确保程序的正确性和性能。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

613

2024.08.29

c++怎么把double转成int
c++怎么把double转成int

本专题整合了 c++ double相关教程,阅读专题下面的文章了解更多详细内容。

334

2025.08.29

C++中int的含义
C++中int的含义

本专题整合了C++中int相关内容,阅读专题下面的文章了解更多详细内容。

235

2025.08.29

硬盘接口类型介绍
硬盘接口类型介绍

硬盘接口类型有IDE、SATA、SCSI、Fibre Channel、USB、eSATA、mSATA、PCIe等等。详细介绍:1、IDE接口是一种并行接口,主要用于连接硬盘和光驱等设备,它主要有两种类型:ATA和ATAPI,IDE接口已经逐渐被SATA接口;2、SATA接口是一种串行接口,相较于IDE接口,它具有更高的传输速度、更低的功耗和更小的体积;3、SCSI接口等等。

1948

2023.10.19

PHP接口编写教程
PHP接口编写教程

本专题整合了PHP接口编写教程,阅读专题下面的文章了解更多详细内容。

658

2025.10.17

php8.4实现接口限流的教程
php8.4实现接口限流的教程

PHP8.4本身不内置限流功能,需借助Redis(令牌桶)或Swoole(漏桶)实现;文件锁因I/O瓶颈、无跨机共享、秒级精度等缺陷不适用高并发场景。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2401

2025.12.29

TypeScript类型系统进阶与大型前端项目实践
TypeScript类型系统进阶与大型前端项目实践

本专题围绕 TypeScript 在大型前端项目中的应用展开,深入讲解类型系统设计与工程化开发方法。内容包括泛型与高级类型、类型推断机制、声明文件编写、模块化结构设计以及代码规范管理。通过真实项目案例分析,帮助开发者构建类型安全、结构清晰、易维护的前端工程体系,提高团队协作效率与代码质量。

26

2026.03.13

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Kotlin 教程
Kotlin 教程

共23课时 | 4.4万人学习

C# 教程
C# 教程

共94课时 | 11.3万人学习

Java 教程
Java 教程

共578课时 | 81.5万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号