news 2026/4/19 20:44:01

单调队列+滑动窗口

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
单调队列+滑动窗口

对应力扣239滑动窗口的最大值

给你一个整数数组nums,有一个大小为k的滑动窗口从数组的最左侧移动到数组的最右侧。你只可以看到在滑动窗口内的k个数字。滑动窗口每次只向右移动一位。
返回滑动窗口中的最大值

暴力解法:

  • 设置左右指针形成固定长度 k的窗口(左指针left,右指针right=left+k-1);
  • 遍历窗口内[left, right]的 k 个元素,找到并记录最大值;
  • 左右指针同时右移 1 位,重复步骤 2,直到窗口滑出数组末尾;
  • 最终将所有窗口的最大值组成数组返回。

时间复杂度为O(n×k)n为数组长度,k为窗口长度

/** * @param {number[]} nums * @param {number} k * @return {number[]} */ var maxSlidingWindow = function(nums, k) { const res = []; const n = nums.length; let left = 0; // 右指针最大为n-1,窗口左边界最大为n-k while (left <= n - k) { let right = left + k - 1; let max = nums[left]; // 遍历当前窗口,找最大值(你的核心思路) for (let i = left; i <= right; i++) { max = Math.max(max, nums[i]); } res.push(max); left++; // 指针右移,窗口滑动 } return res; };

为什么暴力法效率低?(重复计算是关键)

暴力法的致命问题是存在大量重复计算:窗口每次只右移 1 位,相邻两个窗口有 k-1 个元素是重叠的,但暴力法会重新遍历全部 k 个元素找最大值,浪费了重叠部分的计算结果

单调队列(双端队列 Deque)

要解决重复计算问题,核心是用一个特殊队列记录「窗口内可能成为最大值的元素下标」,让队列保持单调递减,这样队列队首永远是当前窗口的最大值下标,窗口滑动时只需维护这个队列,无需遍历窗口。

先理解:单调递减队列的核心规则

队列中存储的是nums 的元素下标(而非值),且满足:下标对应的值从队首到队尾严格单调递减(比如队列里的下标对应值是 [5,3,-1],而非 [3,5,-1])。

队列的3 个核心维护操作(窗口滑动时执行):

  1. 去尾:当新元素进入窗口时,若新元素值 ≥ 队尾下标对应的值,则队尾出队(因为该队尾元素在窗口内,不可能成为后续任何窗口的最大值,直接淘汰),重复此操作直到队列单调递减;
  2. 入队:将新元素的下标加入队尾,此时队列仍保持单调递减;
  3. 删头:若队首下标 ≤ 窗口左边界 - 1(说明队首元素已滑出窗口),则队首出队,保证队首始终在窗口内。
最优解核心步骤(全程只需遍历数组 1 次)
  1. 初始化双端队列 deque(存储下标)、结果数组 res;
  2. 遍历数组 nums 的每个元素,下标为i
    • 步骤 1:去尾→ 维护队列单调递减,淘汰比当前元素小的队尾;
    • 步骤 2:入队→ 将i加入 deque 队尾;
    • 步骤 3:删头→ 移除滑出窗口的队首下标;
    • 步骤 4:记录最大值→ 当i ≥ k-1(说明第一个窗口已形成),将nums[deque[0]](队首是窗口最大值下标)加入 res;
  3. 遍历结束,res 即为所有窗口的最大值数组。

用数组模拟双端队列(shift()删队首、pop()删队尾、push()入队尾)

/** * @param {number[]} nums * @param {number} k * @return {number[]} */ var maxSlidingWindow = function(nums, k) { const res = []; const deque = []; // 双端队列,存储nums的下标,保持单调递减 const n = nums.length; for (let i = 0; i < n; i++) { // 操作1:去尾 - 维护单调递减,淘汰比当前元素小的队尾 while (deque.length && nums[i] >= nums[deque[deque.length - 1]]) { deque.pop(); } // 操作2:入队 - 加入当前元素下标 deque.push(i); // 操作3:删头 - 移除滑出窗口的队首(窗口左边界为i-k+1) while (deque[0] <= i - k) { deque.shift(); } // 操作4:记录最大值 - 第一个窗口形成后(i>=k-1),队首即为当前窗口最大值 if (i >= k - 1) { res.push(nums[deque[0]]); } } return res; };

为什么左边界是i-k+1

你问的这个问题是滑动窗口的核心边界计算规则i-k+1当前遍历下标i作为窗口右边界时,窗口对应的左边界下标,核心推导基于「窗口长度固定为k+ 数组下标从 0 开始」两个前提,下面用大白话 + 数学推导 + 例子讲透,保证一看就懂!

一、核心前提(先记死,所有推导的基础)

  1. 力扣 239 题是固定长度滑动窗口,窗口内元素的个数严格等于k(比如k=3,窗口永远包含 3 个元素);
  2. 数组 / 字符串的下标从 0 开始(这是编程的通用规则,也是边界计算的关键);
  3. 我们遍历数组的下标i始终作为当前窗口的「右边界」(窗口的最后一个元素的下标)。

二、数学公式推导(10 秒看懂,最直观)

我们的目标是:已知窗口右边界下标i+ 窗口长度k,求窗口左边界下标left

第一步:先想「连续数字的个数」计算规则

对于任意连续的下标区间[left, i](left ≤ i),区间内的元素个数计算公式是:元素个数=i−left+1✅ 验证(下标从 0 开始):

  • 区间[0,2]2-0+1=3个元素(0、1、2),正确;
  • 区间[1,3]3-1+1=3个元素(1、2、3),正确;
  • 区间[2,4]4-2+1=3个元素(2、3、4),正确。
第二步:结合「窗口长度 = k」推导左边界

因为固定窗口的元素个数必须等于k,所以代入公式得:k=i−left+1将公式移项求解left(小学一元一次方程):left=i−k+1

这就是i-k+1数学由来,没有任何复杂逻辑,纯粹是「下标从 0 开始」的个数计算规则推导结果。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/18 21:41:52

5种快捷命令!Kali批量检测网站漏洞

大家好&#xff0c;我是Kali与编程讲师老K&#xff0c;致力于帮助小白轻松学会Kali与编程。 还在愁批量检测网站漏洞效率低&#xff1f;别担心&#xff01;接下来你将学会5种超实用的Kali批量检测网站漏洞类型方法&#xff0c;每条命令搞定一个需求&#xff5e; 方法1&#x…

作者头像 李华
网站建设 2026/4/18 22:55:09

Java计算机毕设之基于springboot的宠物领养及健康管理系统基于springboot+vue的宠物领养管理系统(完整前后端代码+说明文档+LW,调试定制等)

博主介绍&#xff1a;✌️码农一枚 &#xff0c;专注于大学生项目实战开发、讲解和毕业&#x1f6a2;文撰写修改等。全栈领域优质创作者&#xff0c;博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围&#xff1a;&am…

作者头像 李华
网站建设 2026/4/17 22:36:16

Java毕设选题推荐:基于springboot+bs架构的校园体育器材管理系统设计与实现基于springboot架构的校园体育器材管理系统设计与【附源码、mysql、文档、调试+代码讲解+全bao等】

博主介绍&#xff1a;✌️码农一枚 &#xff0c;专注于大学生项目实战开发、讲解和毕业&#x1f6a2;文撰写修改等。全栈领域优质创作者&#xff0c;博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围&#xff1a;&am…

作者头像 李华
网站建设 2026/4/18 19:34:46

Java毕设选题推荐:基于springboot的个性化推荐电商平台的设计与实现基于java的个性化推荐的电商购物商城平台【附源码、mysql、文档、调试+代码讲解+全bao等】

博主介绍&#xff1a;✌️码农一枚 &#xff0c;专注于大学生项目实战开发、讲解和毕业&#x1f6a2;文撰写修改等。全栈领域优质创作者&#xff0c;博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围&#xff1a;&am…

作者头像 李华
网站建设 2026/4/18 5:56:55

Java毕设项目推荐-基于springboot的宠物领养及健康管理系统领养中心管理、申请领养管理、领养记录管理、回访信息管理、宠物知识管理【附源码+文档,调试定制服务】

博主介绍&#xff1a;✌️码农一枚 &#xff0c;专注于大学生项目实战开发、讲解和毕业&#x1f6a2;文撰写修改等。全栈领域优质创作者&#xff0c;博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围&#xff1a;&am…

作者头像 李华
网站建设 2026/4/18 6:35:57

认知生态论:一个诊断观念系统的D-O-S元框架及其研究纲领

认知生态论&#xff1a;一个诊断观念系统的D-O-S元框架及其研究纲领 摘要 面对公共领域与学术场域中日益纷繁却彼此割裂的批判话语与观念竞争&#xff0c;本文主张&#xff0c;亟需一种能够对观念系统本身进行“元理论”分析的共同语法。为此&#xff0c;我们提出 “认知生态论…

作者头像 李华