C++单调队列详解

本文详细介绍了单调队列的概念、用途和工作原理,特别是在解决区间最值问题上的应用。通过一个POJ 2823题目实例,阐述了如何使用单调队列以O(n)的时间复杂度找到每个长度为k区间内的最小值/最大值,对比了暴力和线段树方法,突出了单调队列的效率优势。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

单调队列到底是什么呢?

简单地按照字面意思来说,单调队列是一种队列(踢飞)

但是这种队列和普通的队列有着很大的区别,怎么说呢:

它的队首和普通的队列一样,只能删除元素。

而它的队尾既可以添加元素也可以删除元素。

通常来说也可以叫做输入受限的双端队列(栈)。


单调队列是做什么用的呢?

简单来说就是用来维护一段区间内的单调上升/下降性质,导出性质就是也可以用来维护一个区间内的最值。

我们先来看一道例题:poj 2823

题目大意

给你n个数字和一个长度k,让你从前到后输出每个长度为k的区间内的最小值/最大值。

思路

1.暴力 

从前到后每个区间遍历一遍,复杂度是O(n*k),铁定超时了

2.线段树维护区间最值

n的范围是10^6,线段树需要4*10^6的空间貌似不会爆,时间复杂度是O(nlogn),可以接受

但是对这道题而言,单调队列显然是优于线段树的另一种思路,先来了解一下它的

工作原理

假设现在我们维护一个递减(最大值)的单调队列,当一个数据想要入队时,需要执行以下操作:

①从队尾到队首开始遍历,如果碰到元素比待入队元素要小,那么这个元素便失去了作用(因为维护的是最大值,如果有一个比当前值小,那它一定不是最大的),将其出队。直到碰到一个比当前值大的元素,跳出循环;

②从队首开始清除

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值