LC 239.滑动窗口最大值

239.滑动窗口最大值

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

返回 滑动窗口中的最大值

示例 1:

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

滑动窗口的位置 最大值


[1 3 -1] -3 5 3 6 7 3

1 [3 -1 -3] 5 3 6 7 3

1 3 [-1 -3 5] 3 6 7 5

1 3 -1 [-3 5 3] 6 7 5

1 3 -1 -3 [5 3 6] 7 6

1 3 -1 -3 5 [3 6 7] 7

示例 2:

输入: nums = [1], k = 1
输出:[1]

提示:

  • 1 ≤ n u m s . l e n g t h ≤ 1 0 5 1 \leq nums.length \leq 10^5 1nums.length105
  • − 1 0 4 ≤ n u m s [ i ] ≤ 1 0 4 -10^4 \leq nums[i] \leq 10^4 104nums[i]104
  • 1 ≤ k ≤ n u m s . l e n g t h 1 \leq k \leq nums.length 1knums.length

解法一(优先队列)

思路分析:

  1. 对于求滑动窗口的最大值,可以使用优先队列,其中的大根堆可以帮助我们实时维护一系列元素中的最大值
  2. 首先将nums数组的前k个元素放入优先队列中,当向右移动窗口时,将新元素放入优先队列中,此时堆顶的元素是堆中所有元素的最大值,但是这个元素可能不在滑动窗口中
  3. 当最大值不在滑动窗口中时,需要判断该值在数组nums的位置在滑动窗口左边界的左侧,所以在继续移动窗口时,若最大值不在滑动窗口中,则永久移除优先队列
  4. 不断移除堆顶的元素,直到堆顶元素在滑动窗口中,此时堆顶元素为滑动窗口中的最大值
  5. 为了方便判断堆顶元素是否在滑动窗口中,可以使用优先队列存储二元组(num, index)index为元素num在数组中的下标

实现代码如下:

class Solution {
    public int[] maxSlidingWindow(int[] nums, int k) {
		int n = nums.length;	// 数组nums长度
		// 创建 优先队列 并设置堆中元素比较方式
		PriorityQueue<int[]> pq = new PriorityQueue<>(
				(o1, o2) -> o1[0] != o2[0]? o2[0]-o1[0] : o2[1] - o1[1]
		);
		// 先将第一组滑动窗口 添加到优先队列中
		for (int i = 0; i < k; ++ i) {
			pq.offer(new int[]{nums[i], i});
		}
		int[] ans = new int[n-k+1];		// 返回最大值结果数组 且一共有n-k+1个窗口
        ans[0] = pq.peek()[0];
		// 移动滑动窗口 进行遍历
		for (int i = k; i < n; ++ i) {
			pq.offer(new int[]{nums[i], i});	// 将右窗口元素加入到优先队列中
			while (pq.peek()[1] <= i-k) {	// 将不在窗口内的最大值移除
				pq.poll();
			}
			ans[i-k+1] = pq.peek()[0];	// 记录窗口内的最大值
		}
		return ans;
    }
}

提交结果:

解答成功:
执行耗时:90 ms,击败了11.01% 的Java用户
内存消耗:56.2 MB,击败了96.20% 的Java用户

复杂度分析:

  • 时间复杂度: O ( n l o g n ) O(nlog_{}{n}) O(nlogn),维护优先队列中堆顶最大值时间复杂度为 O ( l o g n ) O(log_{}{n}) O(logn),同时需要遍历每个窗口的时间复杂度为 O ( n − k + 1 ) O(n-k+1) O(nk+1),所以综合得时间复杂度为 O ( n l o g n ) O(nlog_{}{n}) O(nlogn)
  • 空间复杂度: O ( n ) O(n) O(n),维护优先队列,保存数组中的元素

解法二(单调队列)

思路分析:

  1. 根据解法一进行优化,可以使用一个队列来维护没有被移除的数组元素的下标,并且这些下标对应的元素是严格单调递减的
  2. 当滑动窗口向右移动时,需要将一个新的元素放入队列中,此时需要新元素与队尾的元素比较,即如果队尾元素小于新元素,则永久移除,保证新的元素小于队尾的元素
  3. 且此时队首元素就是滑动窗口中的最大值,但是与解法一中一样,需要判断最大值是否在滑动窗口中,若不在则弹出,并继续进行判断
  4. 因为需要对队首和队尾的元素进行操作,所以使用双端队列来实现单调队列

实现代码如下:

class Solution {
	public int[] maxSlidingWindow(int[] nums, int k) {
		int n = nums.length;	// 数组nums长度
		Deque<Integer> deque = new ArrayDeque<>();	// 双端队列 用作维护单调队列
		int[] ans = new int[n-k+1];		// 返回结果数组 且计算得滑动窗口数量为n-k+1
		for (int i = 0; i < k; ++i) {	// 将第一组滑动窗口元素加入队列中
			// 将小于新元素的队尾元素 移除队列
			while (!deque.isEmpty() && nums[i] >= nums[deque.peekLast()]) {
				deque.pollLast();
			}
			deque.offerLast(i);	// 将新元素添加到队尾
		}
		ans[0] = nums[deque.peekFirst()];
		for (int i = k; i < n; ++i) {
			// 将队尾小于新元素的数组元素 移除
			while (!deque.isEmpty() && nums[i] >= nums[deque.peekLast()])
				deque.pollLast();
			deque.offerLast(i);		// 将新元素添加到队尾
			// 将队首 不在滑动窗口内的最大值移除
			while (!deque.isEmpty() && deque.peekFirst() <= i-k)
				deque.pollFirst();
			ans[i-k+1] = nums[deque.peekFirst()];
		}
		return ans;
	}
}

提交结果如下:

解答成功:
执行耗时:30 ms,击败了60.89% 的Java用户
内存消耗:63.2 MB,击败了5.02% 的Java用户

复杂度分析:

  • 时间复杂度: O ( n ) O(n) O(n),对每个元素遍历一次,且每个元素进队和出队一次
  • 空间复杂度: O ( n ) O(n) O(n),使用双端队列维护单调队列

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【QT】Ubuntu22.04 配置 QT6.5 LTS

【QT】Ubuntu22.04 配置 QT6.5 LTS 文章目录 【QT】Ubuntu22.04 配置 QT6.5 LTS1.注册QT Group的账号2.安装QT Creator3.启动QT Creator报错from 6.5.0, xcb-cursor0 or libxcb-cursor0 is needed to load the Qt xcb platform plugin.4.运行QT的demoReference 1.注册QT Group的…

mysql buffer pool详解

介绍 缓冲池是InnoDB在访问表和索引数据时缓存的主内存区域。缓冲池允许直接从内存访问频繁使用的数据&#xff0c;这加快了处理速度。在专用服务器上&#xff0c;通常会将多达80%的物理内存分配给缓冲池。 为了提高大容量读操作的效率&#xff0c;缓冲池被划分为可能包含多行…

类与对象(三) 拷贝构造与赋值运算符重载

目录 1.拷贝构造 2.运算符重载&#xff08;日期类举例&#xff09; 1. 2.和 3. > > < < 4.赋值运算符重载 5.- 与- 6. -- 7.日期 - 日期 3.const成员函数 4.<<和>>重载 5.取地址重载 1.拷贝构造 拷贝构造也是一个构造函数。我们前…

Linux:动静态库介绍

动静态库 库的介绍开发环境 & 编译器库存在的意义库的实现库的命名静态库制作和使用总结 动态库的制作和使用动态库的使用方法方法一方法二方法三 库加载问题静态库加载问题动态库的加载问题与位置无关码 C/C静态库下载方式 库的介绍 静态库&#xff1a;程序在编译链接的时…

C++初识--------带你从不同的角度理解引用的巧妙之处

1.对于展开的理解 我们这里的展开包括命名空间的展开和头文件的展开&#xff0c;两者的含义是不一样的&#xff1a; 头文件的展开就是把头文件拷贝到当前的文件里面&#xff1b; 命名空间的展开不是拷贝&#xff0c;而是因为编译器本身默认是到全局里面去找&#xff0c;当我…

一些常见的Windows命令

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言看版本号查找端口启动程序杀死某个端口查看全部端口看ip进入目录就是总结 前言 提示&#xff1a;这里可以添加本文要记录的大概内容&#xff1a; 例如&#x…

Linux——匿名管道

为什么要有进程间通信&#xff1f; 在操作系统中&#xff0c;进程是独立运行的程序&#xff0c;多个进程之间要想互相协作完成任务&#xff0c;就需要进程间通信。 什么是进程间通信&#xff1f; 数据传输&#xff1a;一个进程需要将它的数据发送给另一个进程资源共享&#…

03-JAVA设计模式-解析器模式

解释器模式 什么是解析器模式 在Java中&#xff0c;解释器模式&#xff08;Interpreter Pattern&#xff09;是一种行为设计模式&#xff0c;它给定一个语言&#xff0c;定义它的文法的一种表示&#xff0c;并定义一个解释器&#xff0c;该解释器使用该表示来解释语言中的句子…

六、e2studio VS STM32CubeIDE之代码自动补全

目录 一、概述/目的 二、eclipse c/c自动补全 2.1 修改实现原理 2.2 修改插件cdt.ui的方法 2.2.1 资料来源 2.2.2 修改的主要流程或逻辑 2.2.3 失败的原因 三、呼吁st和Renesas厂家支持自动补全代码 六、e2studio VS STM32CubeIDE之代码自动补全 一、概述/目的 eclipse…

解决:前端bootstrap的fileInput插件

项目场景&#xff1a; 帮朋友做一个后台管理系统遇到文件上传回显异常的问题。 项目是单体架构&#xff0c;没有前后端分离&#xff0c;前端使用的bootstrap3Thymeleaf。上传插件用的是fileInput。 问题描述&#xff1a; 上传没有问题&#xff0c;完成后点击编辑再次进入无…

从本地创建项目到 Gitee 提交的完整教程

1、本地创建一个新项目 2.进入想上传的项目的文件夹&#xff0c;然后右键点击git bash 3.初始化本地环境&#xff0c;把该项目变成可被git管理的仓库 4.添加该项目下的所有文件到暂存区 5.使用如下命令将文件添加到仓库中去 6.在gitee上创建以自己项目名称命名的空项目 7.将本地…

springboot结合elasticJob

先说一说什么是elasticJob。 ElasticJob是一个分布式任务调度的解决方案&#xff0c;它由俩个相互独立的子项目Elastic-job-lite和Elastic- job-cloud组成。 任务调度&#xff1a;是指系统为了自动完成特定任务&#xff0c;在任务的特定时刻去执行任务的过程。 分布式&#xf…

窗函数的选择

不同的窗函数实质上时对矩形窗进行了不同程度的加权得到的不同类型的窗函数。 将模拟角频率转换为了数字角频率 矩形窗旁瓣过大&#xff0c;两个频率的峰值相差较大&#xff0c;因此无法识别&#xff0c;可以使用旁瓣非常小的窗函数来进行分辨&#xff0c;只是想要达到相同的分…

(C++) this_thread 函数介绍

文章目录 &#x1f6a9;前言⭐std::this_thread&#x1f579;️get_id()&#x1f5a5;️Code&#x1f516;get_id介绍&#x1f3f7;️其他介绍 &#x1f579;️sleep_for<>()&#x1f5a5;️Code&#x1f516;sleep_for介绍&#x1f3f7;️其他介绍 &#x1f579;️sleep…

python基础语法--列表

一、列表的概念 列表&#xff08;List&#xff09;是一种有序、可变、允许重复元素的数据结构。列表用于存储一组相关的元素&#xff0c;并且可以根据需要动态地进行增加、删除、修改和访问。以下是列表的主要特点和操作&#xff1a; 有序性&#xff1a; 列表中的元素是按照它…

最新AI创作系统ChatGPT网站源码Midjourney-AI绘画系统,Suno-v3-AI音乐生成大模型。

一、前言 SparkAi创作系统是基于ChatGPT进行开发的Ai智能问答系统和Midjourney绘画系统&#xff0c;支持OpenAI-GPT全模型国内AI全模型。本期针对源码系统整体测试下来非常完美&#xff0c;那么如何搭建部署AI创作ChatGPT&#xff1f;小编这里写一个详细图文教程吧。已支持GPT…

【CVPR2024】文本到图像的行人再识别中的噪声对应学习

这篇论文的标题是《Noisy-Correspondence Learning for Text-to-Image Person Re-identification》,作者是来自中国四川大学、英国诺森比亚大学、新加坡A*STAR前沿人工智能研究中心和高性能计算研究所的研究人员。论文主要研究了文本到图像的行人再识别(Text-to-Image Person…

Unity进阶之ScriptableObject

目录 ScriptableObject 概述ScriptableObject数据文件的创建数据文件的使用非持久数据让其真正意义上的持久ScriptableObject的应用配置数据复用数据数据带来的多态行为单例模式化的获取数据 ScriptableObject 概述 ScriptableObject是什么 ScriptableObject是Unity提供的一个…

Windows抛弃历史包袱:可能带来哪些改善?

在开始前我有一些资料&#xff0c;是我根据网友给的问题精心整理了一份「 Windows的资料从专业入门到高级教程」&#xff0c; 点个关注在评论区回复“888”之后私信回复“888”&#xff0c;全部无偿共享给大家&#xff01;&#xff01;&#xff01;性能提升固然重要&#xff0…

[NSSCTF]-Reverse:[HUBUCTF 2022 新生赛]simple_RE(base64换表)

无壳 查看ida 可以看得出是base64&#xff0c;而且是换表的。 完整exp&#xff1a; import base64 result5Mc58bPHLiAx7J8ocJIlaVUxaJvMcoYMaoPMaOfg15c475tscHfM/8 biaostr.maketrans(qvEJAfHmUYjBacu8Ph5n9Od17FrICL/X0gVtM4Qk6T2z3wNSsyoebilxWKGZpRD,ABCDEFGHIJKLMNOPQR…
最新文章