滑动窗口优先选 deque,因其 popleft() 为 O(1),而 list.pop(0) 为 O(n);需维护单调队列时必须存下标以准确判断元素是否过期;小窗口(≤5)且数据量小时可用 list。

滑动窗口该用 list 还是 deque?
用 list 模拟滑动窗口在频繁 pop(0) 时会退化成 O(n) 时间复杂度,因为每次都要移动后续所有元素;而 collections.deque 的 popleft() 是 O(1)。除非窗口极小(比如固定长度 ≤ 5)且数据量不大,否则默认选 deque。
实操建议:
- 导入写成
from collections import deque,避免每次调用都带模块前缀 - 初始化窗口用
win = deque(maxlen=k)可自动丢弃左端,但注意它不支持随机索引访问,需额外变量存最大/最小值 - 若需频繁查窗口内最值,直接用
deque维护单调队列比反复调用max(win)高效得多
单调队列中存下标还是存值?
必须存下标。只存值无法判断某个元素是否已滑出窗口——因为重复值会导致无法区分“哪个 5 已过期”。下标能精确计算位置,配合当前右边界 r 判断 if q[0] 是否越界。
常见错误现象:
立即学习“Python免费学习笔记(深入)”;
- 窗口最大值突然变小,且不再恢复 → 很可能是用值做判断,把未过期的重复值误删了
- 结果数组长度不对 → 下标没和循环变量对齐,比如用
for i, x in enumerate(nums)但内部仍用i+1当右端点
典型写法片段:
q = deque()
for r in range(len(nums)):
while q and nums[q[-1]] <= nums[r]:
q.pop()
q.append(r)
if q[0] <= r - k:
q.popleft()
if r >= k - 1:
res.append(nums[q[0]])
MATLAB(矩阵实验室)是MATrix LABoratory的缩写,是一款由美国The MathWorks公司出品的商业数学软件。MATLAB是一种用于算法开发、数据可视化、数据分析以及数值计算的高级技术计算语言和交互式环境。除了矩阵运算、绘制函数/数据图像等常用功能外,MATLAB还可以用来创建用户界面及与调用其它语言(包括C,C++和FORTRAN)编写的程序。MATLAB基础知识;命令窗口是用户与MATLAB进行交互作业的主要场所,用户输入的MATLAB交互命令均在命令窗口执行。 感兴趣的朋友可以
固定长度 vs 可变长度滑动窗口怎么选模板?
固定长度(如「长度为 k 的子数组最大值」)适合用双指针 + 单调队列,逻辑集中在右指针推进、左边界自动校验;可变长度(如「和至少为 target 的最短子数组」)则必须显式维护 left 指针,并在内层 while 中收缩。
关键区别点:
- 固定窗口:右指针每步必进,左指针不动或只动一次,
for r in range(n)足够 - 可变窗口:左指针可能连走多步,必须用
while sum_val >= target:循环收缩,且需在收缩后才更新答案 - 性能影响:可变窗口最坏是 O(2n),看似两重循环,但每个元素最多进出窗口各一次,仍是线性
LeetCode 239 题本地调试总输出空列表?
大概率是忘了在 r >= k - 1 时才开始记录结果。比如 k=3,合法窗口从索引 2 开始(0-based),但循环从 r=0 开始,前两轮不能 append。
调试技巧:
- 打印每轮的
r、q、nums[q[0]]和是否 append,比只看最终结果更快定位漏填点 - 用小样例手跑:nums = [1,3,-1,-3,5,3,6,7], k = 3,正确输出应为 [3,3,5,5,6,7],少一个就说明边界条件错
- 注意题目是否要求返回「每个窗口的最大值」还是「所有窗口最大值中的最大值」——后者只需一个变量,不用数组
真正麻烦的是窗口内需同时维护多个统计量(比如最大值 + 最小值 + 出现次数),这时单个 deque 不够用,得拆成多个结构,或者改用平衡二叉树模拟(Python 里常用 sortedcontainers,但 OJ 通常不预装)。










