单调队列

本文介绍了单调队列的概念,包括普通队列、双端队列和单调队列的定义,并强调单调队列在维护区间极值问题中的应用。通过举例说明如何使用单调队列解决求解每相邻k个数中的最大值问题,阐述了单调队列的维护过程和时间复杂度分析,指出其在动态规划中的优化作用。
摘要由CSDN通过智能技术生成

预备知识介绍:

1. 队列
  • 队列 (queue) 是一种特殊的线性表,是符合“先进先出”(first in first out)原则的基本数据结构,因此也常被称作 FIFO 队列或公平队列。
  • 一个队列由队首 (front)、队尾 (rear) 和储存元素的线性表构成。当元素入队时,队尾后移并向线性表中添加新元素;当元素出队时,删除线性表中队首指向的元素,队首后移。一般地,只在队尾入队,在队首出队。对队中元素的讨论都必须建立在队列非空的基础上,否则没有意义。
  • C++ STL 中内置了 queue 容器,实现了普通队列的基本操作,使用时需引用 头文件。
2. 双端队列
  • 双端队列 (deque) 打破了队列的出入队位置限制,允许元素从队首入队或从队尾出队。类似地,在 C++ STL 中内置了 deque 容器,实现了双端队列。
3. 单调队列
  • 单调队列 (monotonic queue) 是指一种所储存的元素具有单调性的特殊双端队列,可根据具体的元素单调性分为单调递增队列、单调递减队列、单调不增队列、单调不减队列四种。前两种要求元素间具有严格的大小关系,不允许相等的元素同时出现在队列中,而后两者允许。
  • 单调队列常常用于维护一个具有特殊性质的区间,求区间极值。一般会对区间长度或其他因素进行限制,因此队列中的元素常常为 (pos,val) 的二元组。在任意时刻,队列中元素的两个值都分别具有单调性,但其性质可能不同。如 pos 一般为单调上升,而 val 则四种情况都有可能。
  • 新元素入队时,为了维护队列的单调性,要不断将队尾元素出队,直到当前元素入队后不会破坏队列单调性为止。取值计算时,为了保证对区间的限制是合法的,要将队首元素不断出队,直到队首元素满足对区间的限制为止。出队和入队的顺序可以调换。详见下面的例子。
  • 在竞赛中单独考察单调队列的情况极少出现,但往往会配合动态规划,对其时间复杂度进行优化。近年来,NOI 系列赛事和部分省选都考察过。

举例分析

下面试举一例,分析单调队列的具体题目中的应用。

给定 n n 个数,分别为 a_1, a_2, \ldots, a_n a1,a2,,an 。要求输出每相邻 k k 个数中的最大值。换言之,即求 max(a_1, a_2, \ldots, a_k),\\ max(a_2, a_3, \ldots, a_{k+1}),\\ \ldots\\ max(a_{n-k+1}, a_{n-k+2}, \ldots, a_n).

max(a1,a2,,ak),max(a2,a3,,ak+1),max(ank+1,
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值