单调队列(利用C++容器deque实现)原理解析

1:关于deque

*deque是C++中的一个容器,其底层原理是双端队列(学过数据结构的应该知道,就是对比于普通的队列而言,可以在双端队列的两端进行插入和删除操作,所以用它来操作数据比较方便,但是注意:其底层存储结构并不是连续的存储单元,所以不能用指针加偏移地址去操作)。
* 其头文件为#include< queue >

2:关于单调队列

单调队列其实是一种思想,也就是维护一个单调递增或者单调递减的队列,如果新插入的值比队尾大,就可以直接插入队列,如果比队尾小,就将队尾弹出,知道队尾元素小于这个插入值。所以即可维护一个单调队列。单调队列可以用来计算某个区间内部的最大值或者最小值。

3:利用deque实现单调队列
根据deque的特点,我们可以很清楚的模拟出实现单调队列的过程。

4:例题

在这里插入图片描述

在这里插入图片描述

//@author:hairu,wu
//@from:ahut
#include<iostream>
#include<queue>
using namespace std;

int n,m;

struct E{
	int num;
	int id;
};

deque<E> q;

int main(){
	cin >> n>> m;
	E e;
	for(int i=1;i<=n;i++){
		int x;
		scanf("%d",&x);
		e.num=x;e.id=i;
		if(i==1){//第一个特别输出 
			q.push_back(e);
			printf("0\n");
			continue;
		}
		//对于本题,需要弹出队头在前m个数字之外的数弹出
		while(!q.empty()&&q.front().id<=i-m-1){
			q.pop_front();
		} 
		//输出在前m个中最小的数字
		printf("%d\n",q.front().num);
		//维护单调队列,如果x大于等于队尾元素,直接插入,如果小于队尾元素,则需要弹出对微元素 
		while(!q.empty()&&q.back().num>=x){
			q.pop_back();
		} 
		q.push_back(e); 
	}
	return 0;
} 
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
deque实现单调队列的关键在于维护队列的单调性。在每次插入元素时,需要将队列尾部小于当前元素的元素弹出,以保证队列的单调递增性。同时,为了实现O(1)的时间复杂度,可以使用双端队列deque实现。 具体实现步骤如下: 1. 使用一个deque来保存递增的元素,队首元素即为当前区间的最小值。 2. 当插入一个新元素时,从队列尾部开始,将所有小于等于新元素的元素都弹出,以保持队列的递增性。 3. 将新元素插入队列尾部。 4. 当需要获取当前区间的最小值时,直接返回队首元素即可。 这样,通过deque实现,我们可以实现单调队列,并且在插入、弹出、获取最小值的操作中都能够达到O(1)的时间复杂度。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [【模板deque实现单调队列](https://blog.csdn.net/weixin_30768661/article/details/99426153)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 33.333333333333336%"] - *2* [剑指Offer – 面试题59 – II. 队列的最大值(deque模拟单调栈)](https://download.csdn.net/download/weixin_38693192/13752480)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 33.333333333333336%"] - *3* [单调队列-原理详解(deque实现)](https://blog.csdn.net/sinat_40471574/article/details/90577147)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 33.333333333333336%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小吴同学GOGOGO

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值