首页 > 其他分享 >单调队列

单调队列

时间:2024-12-01 12:43:37浏览次数:5  
标签:队列 元素 value ++ int 单调

单调队列的定义
顾名思义,单调队列就是队内元素具有单调性的队列。根据需要我们可以直接从队头取出队列中的最大值或最小值,并且剩下的元素仍然具有单调性。

通过一个经典题目来了解单调队列
滑动窗口-AcWing题库

给定一个大小为 n≤106的数组。
有一个大小为 k的滑动窗口,它从数组的最左边移动到最右边。
你只能在窗口中看到 k个数字。
每次滑动窗口向右移动一个位置。
你的任务是确定滑动窗口位于每个位置时,窗口中的最大值和最小值。

首先我们来思考一下暴力的做法,从第一个数开始到第 n-k 个数每次遍历k个数,那么时间复杂度大概就是O(nk),这样当k稍大点时,就会TEL啦。
这时我们就可以用到单调队列了。毕竟满足单调性的话我们只要取队列的队头就可以了,减少了很多不必要的比较。因为窗口中只能看到k个数字,所以
我们要维护一个大小为 k 的单调队列。具体怎么做看代码

点击查看代码
#include<bits/stdc++.h>
using namespace std;
int q1[1000010],q2[1000010],max_value[1000010],min_value[1000010],value[1000010];
int main() {
	int n, k,cnt=0;
	cin >> n >> k;
	int head01 = 0, tail01 = -1,head02=0,tail02=-1;
	for (int i = 0; i < n; i++) {
		cin >> value[i];
	}
	for (int i = 0; i < n; i++) {
		//在队列不为空的情况下,如果队列中的元素多于k个,队头就出队
		while (tail01>=head01&&i-q1[head01] >=k ) head01++;
		//在队列不为空的情况下,如果队尾元素下标对应的值小于要入队的值,
		//说明该元素‘没有成为最大元素的潜力’,队尾元素出队
		while (tail01 >= head01 && value[q1[tail01]] < value[i]) tail01--;
		q1[++tail01] = i;
		//在队列不为空的情况下,如果队列中的元素多于k个,队头就出队
		while (tail02>=head02&&i-q2[head02] >= k) head02++;
		//在队列不为空的情况下,如果队尾元素下标对应的值大于要入队的值,
		//说明该元素‘没有成为最小元素的潜力’,队尾元素出队
		while (tail02 >= head02 && value[q2[tail02]] > value[i]) tail02--;
		//新元素入队
		q2[++tail02] = i;
		//当队内元素达到k个时再记录答案
		if (i >= k - 1) {
			max_value[cnt] = value[q1[head01]];
			min_value[cnt] = value[q2[head02]];
			++cnt;
		}
	}
	for (int i = 0; i < cnt; i++) cout << min_value[i]<<" ";
	cout << "\n";
	for (int i = 0; i < cnt; i++) cout << max_value[i] << " ";
}
容易看出每个元素只会进出队列一次,因此复杂度降为了O(n);

标签:队列,元素,value,++,int,单调
From: https://www.cnblogs.com/Amadeus-maho/p/18579691

相关文章

  • Windows系统使用安装ActiveMQ消息队列手把手保姆级教程踩坑实录
    文章目录一、什么是ActiveMQ1.概述2.架构3.应用场景二、下载ActiveMQ三、解压四、配置环境变量五、启动ActiveMQ六、验证安装和服务七、停止ActiveMQ八、注意事项一、什么是ActiveMQ1.概述ActiveMQ是Apache软件基金下的一个开源软件,它遵循JMS1.1规范(JavaMessage......
  • RabblitMQ 消息队列组件与 libev事件驱动库
    概述RabbitMQ是一个广泛使用的开源消息队列系统,它基于AMQP(高级消息队列协议)。RabbitMQ用于在分布式系统中传递消息,确保消息可靠传递并提供弹性。libev是一个事件驱动的库,用于高效地处理异步事件,常用于网络编程或需要高并发处理的应用。将RabbitMQ与libev结合使用,可以......
  • 【消息队列】RabbitMq-交换机模型
    RabbitMQ交换机模型Fanoutexchange广播形式消息会以广播形式发送给每个绑定该exchange的队列中。Directexchange定向路由在控制台新建了一个exchange,type指定为directTopicexchange以.来分割多个单词,并用通配符来指定routingkey。#:表示0个过多个字母*:表示1个字母......
  • 数据结构——栈和队列
    ......
  • 栈和队列(数据结构)
    一.栈1.1概念与结构栈:一种特殊的线性表,其只允许在固定的一端进行插入和删除元素操作。进行数据插入和删除操作的一端称为栈顶,另一端称为栈底。栈中的数据元素遵守后进先出LIFO(LastInFirstOut)的原则。压栈:栈的插入操作叫做进栈/压栈/入栈,入数据在栈顶。......
  • 力扣每日一题 单调数组对的数目(dp)
     题目困难 动态规划给你一个长度为 n 的 正 整数数组 nums 。如果两个 非负 整数数组 (arr1,arr2) 满足以下条件,我们称它们是 单调 数组对:两个数组的长度都是 n 。arr1 是单调 非递减 的,换句话说 arr1[0]<=arr1[1]<=...<=arr1[n-1] 。arr2......
  • 深入理解 FreeRTOS 队列集(建议收藏!!!)
    在FreeRTOS操作系统这个“大家庭”里,队列集扮演着一个特殊的“管家”角色,它让多个队列之间的协作变得井井有条。一、队列集的基本概念队列集就像是一个专门用来存放其他队列“钥匙”(句柄)的盒子。假设我们有队列A这个“小仓库”,它能存放LengthA数量的“宝贝”(数......
  • 代码随想录第十一天|栈与队列part02--150.逆波兰表达式求值、239.滑动窗口最大值、347
    150.逆波兰表达式求值(150.逆波兰表达式求值)题目分析:计算逆波兰表达式(后缀表达式:左右中)的值,算符仅包含四则运算,操作数为一个整数或另一个表达式,整数除法向零截断(向下取整),无除零运算,答案及中间结果不超过32位,即使用整型int即可。解题重点:后缀表达式的每一个表达式中:读入1个算......
  • 【每日一题】3251. 单调数组对的数目 II
      给你一个长度为 n 的 正 整数数组 nums 。如果两个 非负 整数数组 (arr1,arr2) 满足以下条件,我们称它们是 单调 数组对:两个数组的长度都是 n 。arr1 是单调 非递减 的,换句话说 arr1[0]<=arr1[1]<=...<=arr1[n-1] 。arr2 是单调 非递增 ......
  • 代码随想录算法训练营第三十一天|leetcode56. 合并区间、leetcode738.单调递增的数字
    1leetcode56.合并区间题目链接:56.合并区间-力扣(LeetCode)文章链接:代码随想录视频链接:贪心算法,合并区间有细节!LeetCode:56.合并区间_哔哩哔哩_bilibili思路:其实很清楚,跟之前的方法差不多,但是自己写的时候就是有地方不会了,会不知道接下来的思路是什么1.1视频后的思路卡壳......