【算法与数据结构】239、LeetCode滑动窗口最大值

news2024/11/25 21:49:35

文章目录

  • 一、题目
  • 二、解法
  • 三、完整代码

所有的LeetCode题解索引,可以看这篇文章——【算法和数据结构】LeetCode题解。

一、题目

在这里插入图片描述

二、解法

  思路分析:这道题我们如果用暴力破解法需要 O ( n ∗ k ) O(n*k) O(nk)的复杂度。思索再三,我们需要一个能够把最大值放在队头,整个队列单调递减的单调队列。每次窗口移动的时候,调用que.pop(滑动窗口中移除元素的数值),que.push(滑动窗口添加元素的数值),然后que.front()就返回我们要的最大值。要注意两点:1、最大值必须在队头,这样我们才能用que.front()访问 2、队头的最大值元素必须在滑动窗口内部,否则就不是滑动窗口的最大值

  对于上面两个问题我们分别在pop和push中做这样的逻辑:1、如果队尾元素如果小于入队元素,就弹出队尾元素,直到入队元素大于等于队尾元素才插入入队元素 2、每次访问que.front()之前,都进行一次判断,如果队头的最大值和nums[i-k]进行对比,如果相等,说明这个最大值元素不在滑动窗口中(滑动窗口范围为i-k+1,…,i-1,i)
  程序如下

class MyQueue {	// 单调队列,递减
public:
	deque<int> que;		// deque为双向数组,这里用它当做单调队列的底层实现
	void pop(int value) {	
		if (!que.empty() && value == que.front())	// 如果元素相等则弹出,否则不做操作
			que.pop_front();
	}
	
	void push(int value) {	// 保证队头元素一定是最大的
		while (!que.empty() && value > que.back()) {	// 队尾元素如果小于入队元素,就弹出队尾元素
			que.pop_back();
		}
		que.push_back(value);	// 直到入队元素大于等于队尾元素,插入
	}

	int front() {
		return que.front();
	}
};

class Solution {
public:
	vector<int> maxSlidingWindow(vector<int>& nums, int k) {
		MyQueue que;	// 单调队列
		vector<int> result;
		for (int i = 0; i < k; ++i) {
			que.push(nums[i]);
		}
		result.push_back(que.front());
		for (int i = k; i < nums.size(); ++i) {
			que.pop(nums[i - k]);	// 弹出队头的元素,防止最大值一直在队头,且这个最大值又不在滑动窗口中的情况
			que.push(nums[i]);
			result.push_back(que.front());
		}
		return result;
	}
};

复杂度分析:

  • 时间复杂度: O ( n ) O(n) O(n),所有元素的push和pop操作都只进行一次。
  • 空间复杂度: O ( k ) O(k) O(k),需要一个大小为k的单调队列额外空间。

三、完整代码

# include <iostream>
# include <vector>
# include <deque>
using namespace std;

class MyQueue {	// 单调队列,递减
public:
	deque<int> que;		// deque为双向数组,这里用它当做单调队列的底层实现
	void pop(int value) {	
		if (!que.empty() && value == que.front())	// 如果元素相等则弹出,否则不做操作
			que.pop_front();
	}
	
	void push(int value) {	// 保证队头元素一定是最大的
		while (!que.empty() && value > que.back()) {	// 队尾元素如果小于入队元素,就弹出队尾元素
			que.pop_back();
		}
		que.push_back(value);	// 直到入队元素大于等于队尾元素,插入
	}

	int front() {
		return que.front();
	}
};

class Solution {
public:
	vector<int> maxSlidingWindow(vector<int>& nums, int k) {
		MyQueue que;	// 单调队列
		vector<int> result;
		for (int i = 0; i < k; ++i) {
			que.push(nums[i]);
		}
		result.push_back(que.front());
		for (int i = k; i < nums.size(); ++i) {
			que.pop(nums[i - k]);	// 弹出队头的元素,防止最大值一直在队头,且这个最大值又不在滑动窗口中的情况
			que.push(nums[i]);
			result.push_back(que.front());
		}
		return result;
	}
};

void my_print(vector <int>& v, string msg)
{
	cout << msg << endl;
	for (vector<int>::iterator it = v.begin(); it != v.end(); it++) {
		cout << *it << "  ";
	}
	cout << endl;
}

void VectorGenerator(int* arr, vector<int>& v, int arr_len) {
	for (int i = 0; i < arr_len; ++i) {
		v.push_back(arr[i]);
	}
}

int main()
{
	int window_size = 3;
	int arr[] = {1, 3, -1, -3, 5, 3, 6, 7};
	int arr_len = sizeof(arr) / sizeof(int);
	vector<int> nums;
	VectorGenerator(arr, nums, arr_len);
	my_print(nums, "目标数组");
	Solution s1;
	vector<int> result = s1.maxSlidingWindow(nums, window_size);
	my_print(result, "滑动窗口最大值");
	system("pause");
	return 0;
}

end

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

electron-vue 台称串口对接 SerialPort

大致流程 1.首先找一个串口工具&#xff08;sscom5.12.1&#xff09;试试读取串口是否成功连上&#xff1b; 2.创建electron-vue的项目&#xff1b; 3.安装依赖&#xff0c;调整版本&#xff0c;启动项目&#xff1b;&#xff08;在electron中使用串口_electron 串口_Jack_K…

Eclipse控制台输出log4j日志乱码解决

1. 出现乱码可能是编码格式对应不起来&#xff0c;主要是Eclipse控制台编码和log4j编码的匹配 log4j.properties 主要是查看这两个地方编码一致不一致&#xff0c;如果不一致则手动更改成一致编码&#xff0c;GBK或UTF-8

Ribbon 负载均衡服务调用

文章目录 1 SpringCloud Load Balance2 总结:3 Ribbon工作流程&#xff1a;4 自定义Ribbon 负载均衡算法&#xff1a;4.1 iRule接口&#xff1a;4.2 Ribbon自带的负载均衡算法&#xff1a;4.3 负载均衡算法替代&#xff1a;4.3.1、在非启动类包及子包下创建配置类4.3.2、定义4.…

LayUI动态选项卡的使用

目录 一、Tab选项卡 1.什么是Tab选项卡 2.Tab选项卡的作用 二、Tab选项卡的详细使用步骤 1.参考官网&#xff0c;选择自己喜欢的选项卡 ​ 2.将静态选项卡转换成动态选项卡 3.将选项卡的标签名变成实际菜单名 4.重名选项卡不能二次打开 5.切换到指定选项卡 6.iframe的…

Python示例解释观察者模式

观察者模式是一种常用的设计模式&#xff0c;用于在对象之间建立一种一对多的依赖关系&#xff0c;当一个对象的状态发生变化时&#xff0c;所有依赖于它的对象都会得到通知并自动更新。下面通过一个简单的例子来解释观察者模式的概念。 假设我们有一个名为"主题"&a…

神经网络万能近似定理探索与实验

神经网络万能近似定理探索与实验 今天&#xff0c;我们来做神经网络万能近似定理的探索与实验。关于万能近似定理呢&#xff0c;就是说&#xff0c;对这个神经元的输出进行非线性激活函数处理&#xff0c;单层的神经网络就可以拟合任何一个函数。 下面先看我们搭建的第一个网…

docker部署达梦数据库

一、下载安装包 安装步骤&#xff1a; 先跟着网页走 注&#xff1a;第二步导入安装包&#xff0c;如果是在自己电脑上&#xff0c;就不一定要拷贝到/opt目录下&#xff0c;在安装包所在目录地址栏输入cmd&#xff0c;进入终端进行操作即可 操作到正常打印日志&#xff08;如…

java项目之房屋租赁系统(ssm+mysql+jsp)

风定落花生&#xff0c;歌声逐流水&#xff0c;大家好我是风歌&#xff0c;混迹在java圈的辛苦码农。今天要和大家聊的是一款基于ssm的房屋租赁系统。技术交流和部署相关看文章末尾&#xff01; 开发环境&#xff1a; 后端&#xff1a; 开发语言&#xff1a;Java 框架&…

尚硅谷Docker实战教程-笔记14【高级篇,Docker容器监控之CAdvisor+InfluxDB+Granfana、Docker终章总结】

尚硅谷大数据技术-教程-学习路线-笔记汇总表【课程资料下载】视频地址&#xff1a;尚硅谷Docker实战教程&#xff08;docker教程天花板&#xff09;_哔哩哔哩_bilibili 尚硅谷Docker实战教程-笔记01【基础篇&#xff0c;Docker理念简介、官网介绍、平台入门图解、平台架构图解】…

centos7.9 连续登录失败处理

如果有人恶意破解你的服务器&#xff0c;下面的操作可以起到一定的作用&#xff0c;连续登录失败锁定账户一段时间&#xff0c;让攻击者的成本增加&#xff0c;从而降低服务器被恶意破解的风险。 参考博客 https://blog.csdn.net/hjxloveqsx/article/details/129004832 https…

MyBatis 中如何使用分页

MyBatis 中如何使用分页 在实际的项目开发中&#xff0c;我们经常需要对数据库中的数据进行分页查询&#xff0c;以提高数据查询的效率和用户体验。MyBatis 是一种流行的 Java 持久层框架&#xff0c;它提供了多种分页查询的方式&#xff0c;本文将介绍其中常用的两种方式&…

MySQL数据库详解

文章目录 引言1. SQL1.1 SQL通用语法1.2 SQL分类1.3 DDL1.3.1 数据库操作1.3.2 表操作1.3.2.1 表操作-查询创建1.3.2.2 表操作-数据类型1.3.2.3 表操作-修改1.3.2.3 表操作-删除 1.4 DML1.4.1 添加数据1.4.2 修改数据1.4.3 删除数据 1.5 DQL1.5.1 基本语法1.5.2 基础查询1.5.3 …

车载以太网之SOME/IP-SD专题篇

前言 首先,请问大家几个小小问题,你清楚: 你知道什么是SOME/IP SD吗?SOME/IP-SD报文是如何发送与接收的呢?SOME/IP-SD 存在哪几种Entry Type呢?SOME/IP-SD内部状态机转换又是如何?今天,我们就来一起探索并回答这些问题。为了便于大家理解,以下是本文的主题大纲: 目录…

Sentinel 规则详解

Sentinel 规则 流控规则 flow1、QPS流控2、并发线程数流控3、流控模式4、流控效果 熔断&#xff08;降级&#xff09;规则 degrade1、慢调用比例2、异常比例3、异常数 热点规则 param-flow授权规则 authority1、应用场景2、自定义来源3、授权规则配置 系统规则 前言&#xff1a…

代码随想录day1 | 704.二分查找 27.移除元素

一、二分 1、二分易错点 1、循环变量 while(left < right) 还是while(left <right)2、判断条件 if(num[mid] > tar) mid right 还是 mid right -12、循环不变量 [left, right] [left, right) (left, right]3、左闭右闭写法 当时左闭右闭时&#xff0c;while循…

2、基于kubeadm搭建K8S环境

目录 一、环境说明 二、初始化所有节点 三、修改三台服务器主机名&#xff0c;并写入host文件 四、调整内核参数 五、所有节点安装Docker 六、所有节点配置K8S源 七、所有节点安装kubeadm&#xff0c;kubelet和kubectl 八、部署 kubernetes Master 节点 九、k8s-node …

基于docker的keepalived+MySQL主从实现MySQL高可用

因生产需要对MySQL做高可用&#xff0c;同时&#xff0c;资源有限&#xff0c;因此采用双节点主从keepalived方式实现高勇。另外因需要大批量部署MySQL集群&#xff0c;需要采用模板化部署&#xff0c;本方案采用将MySQL容器化&#xff0c;实现MySQL模板化配置部署。 部署环境及…

SpringMVC学习笔记--上篇

SpringMVC学习笔记 1、SpringMVC 1.1、什么是SpringMVC Spring MVC是Spring Framework的一部分&#xff0c;是基于Java实现MVC的轻量级Web框架。 1.2、SpringMVC的特点 Spring MVC的特点&#xff1a; 轻量级&#xff0c;简单易学高效 , 基于请求响应的MVC框架与Spring兼容…

Python深度学习-有向图合并、排序、最长路径计算

一、有向图方向、权重表示方法 Python通常使用有向图中边的起点和终点来表示边的方向。例如&#xff0c;如果有一条从节点A到节点B的边&#xff0c;则可以使用以下方式表示该有向边&#xff1a; graph {A: {B: 1} }在这个例子中&#xff0c;节点A和节点B之间存在一条权重为1…