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

【LeetCode 热题 100】239. 滑动窗口最大值——(解法一)滑动窗口+暴力解

文章目录

  • 整体思路
  • 完整代码
  • 时空复杂度
    • 时间复杂度:O(N)
    • 空间复杂度:O(k)

整体思路

这段代码旨在高效地解决 “滑动窗口最大值” 问题。与上一个 O(N*k) 的暴力解法不同,此版本采用了 单调队列(Monotonic Queue) 的核心思想,这是一种专门为此类问题设计的优化数据结构,能将时间复杂度降至线性级别。

算法的核心在于维护一个单调递减的双端队列 win。这个队列有以下几个关键特性:

  1. 存储内容:队列中存储的不是元素值,而是元素在原数组 nums 中的 索引
  2. 单调性:队列中的索引所对应的 nums 值是严格单调递减的。即 nums[win[0]] > nums[win[1]] > nums[win[2]] ...
  3. 队首即最大值:由于队列的单调性,队首元素 win.peekFirst() 始终是当前窗口内最大值的索引。

算法的执行步骤如下:

  1. 初始化

    • 创建一个结果数组 ans
    • 创建一个双端队列 win 作为单调队列。
  2. 滑动窗口与单调队列维护

    • 算法使用 right 指针从左到右遍历 nums 数组。对于每个新元素 nums[right]
      a. 维护单调性(队尾操作)
      • 进入一个 while 循环,从队尾开始检查。如果队尾索引对应的元素 nums[win.peekLast()] 小于或等于当前要入队的新元素 nums[right],则将队尾元素弹出(win.pollLast())。
      • 这个过程会持续进行,直到队尾元素大于新元素,或者队列为空。这确保了所有比新元素小的“旧”元素都被清除,因为它们在未来的窗口中不可能成为最大值。
      • 完成清理后,将当前元素的索引 right 加入队尾(win.offerLast(right))。
        b. 维护窗口大小(队首操作)
      • 检查队首元素的索引 win.peekFirst() 是否已经滑出当前窗口的左边界。窗口的左边界是 right - k + 1。如果队首索引小于这个边界(等价于 right - win.peekFirst() + 1 > k),说明队首元素已过期,需要从队首弹出(win.pollFirst())。
        c. 记录结果
      • 当窗口形成后(right >= k - 1),根据单调队列的性质,此时的队首元素 win.peekFirst() 就是当前窗口最大值的索引。
      • nums[win.peekFirst()] 存入结果数组 ans 的相应位置。
  3. 返回结果

    • 遍历结束后,返回 ans 数组。

通过这种方式,每个元素最多入队一次、出队一次,使得在整个过程中找到所有窗口最大值的均摊时间复杂度为 O(1),从而实现了整体的线性时间复杂度。

完整代码

class Solution {/*** 计算滑动窗口的最大值(优化版)。* @param nums 整数数组* @param k 窗口大小* @return 包含每个窗口最大值的数组*/public int[] maxSlidingWindow(int[] nums, int k) {int n = nums.length;// 计算结果数组的长度int m = n - k + 1;int[] ans = new int[m];// win: 一个双端队列,用作单调队列,存储元素的索引。// 队列中的索引对应的 nums 值保持单调递减。Deque<Integer> win = new ArrayDeque<>();// right 指针作为窗口的右边界,遍历整个数组for (int right = 0; right < n; right++) {// 步骤 1: 维护队列的单调递减性// 当队列不为空,且队尾索引对应的元素小于或等于当前元素时,// 将队尾元素弹出。因为这个较小的元素在未来不可能成为最大值。while (!win.isEmpty() && nums[win.peekLast()] <= nums[right]) {win.pollLast();}// 将当前元素的索引加入队尾win.offerLast(right);// 步骤 2: 维护窗口的有效范围// 检查队首元素的索引是否已经滑出窗口左边界。// 窗口的左边界是 right - k + 1。如果队首索引小于它,则说明已过期。// (right - win.peekFirst() + 1) 是队首元素和当前元素构成的窗口大小。if (right - win.peekFirst() + 1 > k) {// 弹出过期的队首元素win.pollFirst();}// 步骤 3: 记录结果// 当窗口大小达到 k 时(即 right 遍历到第 k-1 个元素时),开始记录最大值if (right >= k - 1) {// 由于队列的单调性,队首元素始终是当前窗口内最大值的索引ans[right - k + 1] = nums[win.peekFirst()];}}return ans;}
}

时空复杂度

时间复杂度:O(N)

  1. 循环:代码的主体是一个 for 循环,它遍历 nums 数组一次,执行 N 次。
  2. 队列操作
    • while 循环中的 win.pollLast()if 判断中的 win.pollFirst() 操作看起来可能导致时间复杂度升高。
    • 然而,每个元素的索引最多只会入队一次和出队一次
    • offerLast 将每个索引 0N-1 各压入一次,总共 N 次。
    • pollLastpollFirst 共同将这些索引弹出,每个索引最多被弹出一次。
    • 因此,所有队列操作的总次数是 O(N) 级别的。将这些操作的成本均摊N 次外层循环中,每次循环的均摊时间复杂度为 O(1)

综合分析
算法由 N 次均摊时间复杂度为 O(1) 的操作组成。因此,总的时间复杂度是 O(N)

空间复杂度:O(k)

  1. 主要存储开销:算法使用了一个双端队列 win 来存储索引。
  2. 空间大小:队列 win 中存储的是当前有效窗口内的候选最大值的索引。在任何时刻,队列的长度都不会超过窗口大小 k。例如,如果输入数组是严格递减的,如 [5, 4, 3, 2, 1]k=3,队列会存储 [i, i+1, i+2] 三个索引。因此,队列的最大空间占用为 O(k)
  3. 结果数组ans 数组的空间为 O(N),但不计入额外辅助空间。

综合分析
算法所需的额外辅助空间主要由单调队列 win 决定,其大小与窗口大小 k 成正比。因此,空间复杂度为 O(k)

【LeetCode 热题 100】239. 滑动窗口最大值——(解法三)滑动窗口+单调队列+数组

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/diannao/89331.shtml
繁体地址,请注明出处:http://hk.pswp.cn/diannao/89331.shtml
英文地址,请注明出处:http://en.pswp.cn/diannao/89331.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

MySQL 8.0 连接 5.x 服务器认证问题

总的来说&#xff0c;答案是&#xff1a;可以&#xff0c;但是需要特别注意认证方式的兼容性问题。 MySQL 8.0 引入了新的默认认证插件 caching_sha2_password&#xff0c;而 MySQL 5.x&#xff08;及更早版本&#xff09;使用的是 mysql_native_password。当你用一个 8.0 的客…

Spring原理揭秘(一)

什么是spring&#xff1f; spring框架是一个轻量级的开源的JavaEE框架。 所谓轻量级则是&#xff1a;占用空间小&#xff0c;代码侵入性低&#xff0c;代码耦合度低&#xff0c;降低代码复杂度&#xff0c;可以轻易适配多种框架。 随着spring的不断发展&#xff0c;它所占用…

Visual Studio Code自用搜索技巧整理

多文件跨行搜索 用途 在多个日志文件中搜索跨行日志 方法 1.用VS Code打开待搜索文件所在的目录&#xff1b; 2.按快捷键&#xff08;CtrlShiftF&#xff09;打开全局搜索&#xff1b; 3.点击搜索框右侧的开启正则表达式&#xff1b; 4.输入正则表达式&#xff0c;例如&…

Axure PR 9 验证码登录 案例

大家好&#xff0c;我是大明同学。 这期内容&#xff0c;我们来用Axure来制作一个短信验证登录页面的小案例。 验证码登录小案例 创建手机号输入框所需的元件 1.打开一个新的 RP 文件并在画布上打开 Page 1。 2.在元件库中拖出一个矩形元件&#xff0c;选中矩形元件&#xf…

监听器模式

1. 问题背景 假设我们有一个 银行账户管理系统&#xff0c;该系统需要监控用户账户余额的变动&#xff0c;并在发生变动时&#xff0c;自动执行一些相关的操作&#xff0c;比如发送 余额变动通知&#xff08;如短信、邮件等&#xff09;。为了实现这一功能&#xff0c;我们希望…

帕鲁杯应急响应赛题:知攻善防实验室

一、背景信息 在这个跳跃的数字舞台上&#xff0c;数据安全成了政企单位稳航的重要压舱石。某政企单位&#xff0c;作为一艘驶向未来 的巨轮&#xff0c;对数据的把控丝毫不敢松懈。眼下&#xff0c;我们即将启航一场无与伦比的探险——“信息安全探索之 旅”。 这趟旅程的目的…

【硬核数学】2.2 深度学习的“微积分引擎”:自动微分与反向传播《从零构建机器学习、深度学习到LLM的数学认知》

欢迎来到本系列的第七篇文章。在上一章&#xff0c;我们用张量武装了我们的线性代数知识&#xff0c;学会了如何描述和操作神经网络中的高维数据流。我们知道&#xff0c;一个神经网络的“前向传播”过程&#xff0c;就是输入张量经过一系列复杂的张量运算&#xff08;矩阵乘法…

DAY 45 Tensorboard使用介绍

浙大疏锦行https://blog.csdn.net/weixin_45655710知识点回顾&#xff1a; tensorboard的发展历史和原理tensorboard的常见操作tensorboard在cifar上的实战&#xff1a;MLP和CNN模型 作业&#xff1a;对resnet18在cifar10上采用微调策略下&#xff0c;用tensorboard监控训练过程…

2023年全国硕士研究生招生考试英语(一)试题总结

文章目录 题型与分值分布完形填空错误 1&#xff1a;考察连词 or 前后内容之间的逻辑关系错误2&#xff1a;错误3&#xff1a;错误4&#xff1a;这个错得最有价值&#xff0c;因为压根没读懂错误5&#xff1a;学到的短语&#xff1a; 仔细阅读排序/新题型翻译小作文大作文 题型…

react-数据Mock实现——json-server

什么是mock&#xff1f; 在前后端分离的开发模式下&#xff0c;前端可以在没有实际后端接口的支持下先进行接口数据的模拟&#xff0c;进行正常的业务功能开发 json-server实现数据Mock json-server是一个node的包&#xff0c;可以在不到30秒内获得零编码的完整Mock服务 实现…

使用POI导入解析excel文件

首先校验 /*** 校验导入文件* param file 上传的文件* return 校验结果&#xff0c;成功返回包含成功状态的AjaxResult&#xff0c;失败返回包含错误信息的AjaxResult*/private AjaxResult validateImportFile(MultipartFile file) {if (file.isEmpty()) {return AjaxResult.er…

从0开始学习计算机视觉--Day06--反向传播算法

尽管解析梯度可以让我们省去巨大的计算量&#xff0c;但如果函数比较复杂&#xff0c;对这个损失函数进行微分计算会变得很困难。我们通常会用反向传播技术来递归地调用链式法则来计算向量每一个方向上的梯度。具体来说&#xff0c;我们将整个计算过程的输入与输入具体化&#…

企业流程知识:《学习观察:通过价值流图创造价值、消除浪费》读书笔记

《学习观察&#xff1a;通过价值流图创造价值、消除浪费》读书笔记 作者&#xff1a;迈克鲁斯&#xff08;Mike Rother&#xff09;&#xff0c;约翰舒克&#xff08;John Shook&#xff09; 出版时间&#xff1a;1999年 历史地位&#xff1a;精益生产可视化工具的黄金标准&am…

Day02_C语言IO进程线程

01.思维导图 02.将当前的时间写入到time. txt的文件中&#xff0c;如果ctrlc退出之后&#xff0c;在再次执行支持断点续写 1.2022-04-26 19:10:20 2.2022-04-26 19:10:21 3.2022-04-26 19:10:22 //按下ctrlc停止&#xff0c;再次执行程序 4.2022-04-26 20:00:00 5.2022-04-26 2…

FFmpeg中TS与MP4格式的extradata差异详解

在视频处理中&#xff0c;extradata是存储解码器初始化参数的核心元数据&#xff0c;直接影响视频能否正确解码。本文深入解析TS和MP4格式中extradata的结构差异、存储逻辑及FFmpeg处理方案。 &#x1f4cc; 一、extradata的核心作用 extradata是解码必需的参数集合&#xff0…

【CV数据集介绍-40】Cityscapes 数据集:助力自动驾驶的语义分割神器

&#x1f9d1; 博主简介&#xff1a;曾任某智慧城市类企业算法总监&#xff0c;目前在美国市场的物流公司从事高级算法工程师一职&#xff0c;深耕人工智能领域&#xff0c;精通python数据挖掘、可视化、机器学习等&#xff0c;发表过AI相关的专利并多次在AI类比赛中获奖。CSDN…

SAP月结问题9-FAGLL03H与损益表中研发费用金额不一致(FAGLL03H Bug)

SAP月结问题9-FAGLL03H与损益表中研发费用金额不一致(S4 1709) 财务反馈&#xff0c;月结后核对数据时发现FAGLL03H导出的研发费用与损益表中的研发费用不一致&#xff0c;如下图所示&#xff1a; 对比FAGLL03H与损益表对应的明细&#xff0c;发现FAGLL03H与损益表数据存在倍数…

HTML inputmode 属性详解

inputmode 是一个 HTML 属性&#xff0c;用于指定用户在编辑元素或其内容时应使用的虚拟键盘布局类型。它主要影响移动设备和平板电脑的输入体验。 语法 <input inputmode"value"> <!-- 或 --> <textarea inputmode"value"></texta…

软考中级【网络工程师】第6版教材 第1章 计算机网络概述

考点分析&#xff1a; 本章重要程度&#xff1a;一般&#xff0c;为后续章节做铺垫&#xff0c;有总体认识即可&#xff0c;选择题1-2分高频考点&#xff1a;OSI模型、TCP/IP模型、每个层次的功能、协议层次新教材变化&#xff1a;删除网络结构、删除X.25、更新互联网发展【基本…

Mysql事务与锁

数据库并发事务 数据库一般都会并发执行多个事务&#xff0c;多个事务可能会并发的对相同的一批数据进行增删改查操作&#xff0c;可能就会导致我们说的脏写、脏读、不可重复读、幻读这些问题。为了解决这些并发事务的问题&#xff0c;数据库设计了事务隔离机制、锁机制、MVCC多…