单调队列的应用

单调队列(含多种应用) 这里我只给出ac代码和其应用,其实我也很想给出详细教学, 但大佬们的题解是真的通俗易懂(会在文章下方留下)。 一定要理解它,不要死记代码 ! ୧꒰•̀ᴗ•́꒱୨ 阅读详情

一、

描述
给定一个长度为n(n<=10^6)的数组。有一个大小为k的滑动窗口从数组的最左端移动到最右端。你可以看到窗口中的k个数字。窗口每次向右滑动一个数字的距离。
下面是一个例子:
数组是 [1 3 -1 -3 5 3 6 7], k = 3。

窗口位置最小值最大值
[1  3  -1] -3  5  3  6  7 -13
 1 [3  -1  -3] 5  3  6  7 -33
 1  3 [-1  -3  5] 3  6  7 -35
 1  3  -1 [-3  5  3] 6  7 -35
 1  3  -1  -3 [5  3  6] 7 36
 1  3  -1  -3  5 [3  6  7]37


你的任务是得到滑动窗口在每个位置时的最大值和最小值。


输入
输入包括两行。
第一行包括n和k,分别表示数组的长度和窗口的大小。
第二行包括n个数字。
输出
输出包括两行。
第一行包括窗口从左至右移动的每个位置的最小值。
第二行包括窗口从左至右移动的每个位置的最大值。
样例输入
8 3
1 3 -1 -3 5 3 6 7
样例输出
-1 -3 -3 -3 3 3
3 3 5 5 6 7


构造一个单调队列并进行维护。以求最小值为例,构造一个队列存储元素的下标,每有一个新的元素,如果队列为空直接插入,若非空,则从队尾开始比较将大于插入元素的都清除,然后插入新元素作为备选。(新元素的下标比旧元素靠后,所以旧元素中比新元素值大的就失去了作为备用最小值的意义,可以清除掉不管)同时,若队首元素超出范围则清除。求最大值的也类似。

e.g . 拿样例来说,元素存放在arr[]中,构造队列que{}。n为8,k为3.

插入扫过第一个元素,直接把下标放入得到que{0}。第二个元素3>1,放入下标后的到que{0,1}.第三个元素-1<1,将数值1和3的下标清除 ,放入下标后得到que{2},这是输出arr[2].第四个元素-3<-1,得到que{3},输出arr[3],第五个5>-3.得到que{3.4}....


#include <iostream>
#include <cstdio>

using namespace std;

int arr[1000000];
int que[1000000];
int head = 0, rear = -1;

int empty()
{
    return rear < head;
}

int main()
{
    int n, k;
    scanf("%d%d", &n, &k);
    for(int i = 0; i < n; i++) scanf("%d", &arr[i]);

    int  i = 0;
    //最小值
    while(i < n){     
        while(arr[i] <= arr[que[rear]] && rear >= head) rear--; //找到新插入元素的位置,并清除大于该元素的旧元素
        que[++rear] = i;  //插入新元素的下标
        
        while(!empty() && que[head] < i-k+1) head++;  //清除队首超出范围的元素   
        if(i >= k-1) printf("%d ", arr[que[head]]);  //输出队首(最小值)
        i++;
    }
    printf("\n");

    i = head = 0;
    rear = -1;
    while(i < n){
        while(arr[i] >= arr[que[rear]] && rear >= head) rear--;
        que[++rear] = i;
        
        while(!empty() && que[head] < i-k+1) head++;   
        if(i >= k-1) printf("%d ", arr[que[head]]);
        i++;
    }

    return 0;
}



二、

描述

农夫John 的N(1 ≤ N ≤ 80,000)只奶牛中,有一些也许正在经历发型糟糕的一天。每只奶牛对自己乱糟糟的发型都有自知之明,农夫John想知道所有奶牛能看到其他奶牛头顶的数量之和。

任意奶牛i身高记为 hi (1 ≤ hi ≤ 1,000,000,000),所有奶牛面向东方(本题示意图的右面)依次站成一条线。因此,奶牛i能够看到在它前面的(奶牛i+1,i+2…)所有身高比它低的奶牛,直到被一头比它高的奶牛挡住

考虑如下的例子:

        =
=       =
=   -   =         Cows facing right ->
=   =   =
= - = = =
= = = = = =
1 2 3 4 5 6 

奶牛#1 可以看见奶牛#2, 3, 4的头顶

奶牛#2 无法看到任何奶牛的头顶

奶牛#3可以看见奶牛#4的头顶

奶牛#4无法看到任何奶牛的头顶

奶牛#5可以看见奶牛#6的头顶

奶牛#6无法看到任何奶牛的头顶!

用ci表示奶牛i能够看到头顶的奶牛个数;请计算c1 至cN的和。对于上面这个例子,其和为:3 + 0 + 1 + 0 + 1 + 0 = 5。

输入
第1行:奶牛数N


第2行至N+1行:第i+1行包含一个整数,表示奶牛i的高度

输出
第1行:c1 至cN的累加和
样例输入
6
10
3
7
4
12
2
样例输出
5

  这道题目跟上一道类似,可以通过维护一个单调递减队列实现。构造一个单调递减队列存储高度,每次插入一个新元素时,清除比该元素小的元素(因为高度小被当前奶牛挡住了,不用再计算了),该元素作为队尾元素,此时排在该元素前面的都是比他高的都能看见他,所以ans += rear-head;

#include <iostream>

using namespace std;


int que[80000];
int head = 0, rear = -1;

int main()
{
    int n, input;
    long long ans = 0;
    cin >> n;
    while(n--){
        cin >> input;
        while(rear >= head && input >= que[rear]) rear--; //清除矮的
        que[++rear] = input; //插入
        ans += rear - head;  //统计
    }

    cout << ans << endl;
    return 0;
}








单调队列应用介绍 队列(Queue)是另一种操作受限的线性表,只允许元素从队列的一端进,另一端出,具有先进先出(FIFO)的特性。但**单调队列(Monotonic Queue)**是一种特殊的队列,它首先是一个双端队列(可在队头/队尾进行读写),其次队列内部的元素单调递增/递减。当前最优解在队头插入元素都是从队尾插入会剔除队尾不符合单调性的元素(类似栈的出栈动作)会弹出队头不满足区间限制的元素(单调队列解决的问题一般都带有区间限制)因此,可以把 单调队列看作是滑动窗口和单调栈的组合体。 阅读详情

相关推荐

保姆级教程:用CANoe的LIN Slave Conformance Tester搞定一致性测试(附LDF配置避坑点)

本文详细介绍了如何使用CANoe的LIN Slave Conformance Tester进行汽车电子LIN从节点一致性测试,包括测试环境搭建、LDF文件配置、多通道测试技巧及常见问题解决方案。通过实战案例和高级配置技巧,帮助工程师高效完成测试任务,确保LIN总线通信的可靠性。

weixin_30385925的博客 523

单调队列——滑动窗口

单调队列优化: 以输出每个位置滑动窗口中的最小值为例,在当前“窗口”时,若两个数满足:i<j,ai>aj, 那么ai永远不会作为答案输出,我们可以把ai删掉(出队),删除这样的逆序对后,队列中的元素就是一个单调递增的序列,在队尾插入x时,判断队尾元素>=x,就将队尾元素删除(出队)。这时,我们输出队头元素,就是滑动窗口中的最小值。您的任务是确定滑动窗口位于每个位置时,窗口中的最大值和最小值。第一行输出,从左至右,每个位置滑动窗口中的最小值。第二行输出,从左至右,每个位置滑动窗口中的最大值。

灯火阑珊_ 602

【硬件相关】IB网与以太网核心技术解析及高性能网络部署指南

本文深入解析了IB网与以太网的核心技术差异,包括协议栈、流量控制机制及硬件架构,并提供了高性能网络部署的实战指南。通过对比测试和调优案例,展示了IB网在低延迟和高负载下的优势,以及混合组网中的创新应用,助力超算集群和高效网络部署。

weixin_29311017的博客 99

2020-10-11

第三章 栈与队列 1:滑动窗口 描述 给定一个长度为n(n<=10^6)的数组。有一个大小为k的滑动窗口从数组的最左端移动到最右端。你可以看到窗口中的k个数字。窗口每次向右滑动一个数字的距离。 下面是一个例子: 数组是 [1 3 -1 -3 5 3 6 7], k = 3。 窗口位置 最小值 最大值 [1 3 -1] -3 5 3 6 7 -1 3 1 [3 -1 -3] 5 3 6 7 -3 3 1 3 [-1 -3 5] 3 6 7 -3 5 1 3 -1

weixin_45637770的博客 1241

STM32F4_DHT11数字温湿度传感器

开机的时候先检测是否有DHT11存在,如果没有,则提示错误。DHT11和DS18B20相同,传感器输出的都是未编码的二进制数字。本节我们将利用STM32F4来读取DHT11的温湿度传感器,获取环境的温度和湿度值。因此:温湿度的读取方式就是整数部分的二进制转换成十进制放在整数部分;小数部分的二进制转换成十进制放在小数部分。DHT11和MCU的一次通讯时间最大3ms,主机连续向DHT11采样的间隔建议不小于100ms。DHT11是广州奥松有限公司生产的一款温湿度一体化的数字传感器。数据分小数部分和整数部分。

light_2025的博客 3431

2025年CSP-X初赛真题及答案解析(江西)(完善程序第1题)

2025年CSP-X初赛真题及答案解析(江西)(完善程序第1题)

王老师青少年编程 713

1772: 【基础】滑动窗口

单调对列解决滑动窗口

qq_53335070的博客 937

30分钟用 Restful ABAP Programming(RAP)模型开发一个支持增删改查的 Fiori 应用

2016年时,Jerry曾经写过一系列关于SAP Fiori Smart Template(现在更名为Fiori Elements了)的博客,介绍了所谓的MDD开发方法论 - Metadata Driven Development,即通过开发维护了对应annotation(注解)的CDS view,结合SAP WebIDE,能够花费最少的编程代价,就能够在短时间内获得一个支持增删改查的Fiori应......

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 5951

【单调队列】--滑动窗口

题目链接 给定一个大小为n≤106n≤106的数组。 有一个大小为k的滑动窗口,它从数组的最左边移动到最右边。 您只能在窗口中看到k个数字。 每次滑动窗口向右移动一个位置。 以下是一个例子: 该数组为[1 3 -1 -3 5 3 6 7],k为3。 窗口位置最小值最大值 [1 3 -1] -3 5 3 6 7 -1 3 1 [3 -1 -...

566

ISO2626 --- Item Definition相关项定义

本文并不是针对ISO26262的一个项目,而是针对ISO26262的规范,我们在相关项定义阶段,我们需要做什么,我们的文档需要包含哪些内容的一个描述。

wj博客 909

6-2 GPU GART 绑定机制与 TLB 失效

本文详细解析了AMD GPU的GART(Graphics Address Remapping Table)绑定机制实现。主要内容包括: 绑定流程:从ttm_tt_bind()到硬件PTE更新的完整调用链,重点分析amdgpu_gart_bind()函数实现。 关键函数: amdgpu_gart_bind():执行安全检查、记录映射关系、更新页表等操作 amdgpu_gart_map():将CPU页映射为多个GPU页并填充PTE amdgpu_gmc_set_pte_pde():处理硬件特定的PTE格式 内存

图形/计算GPU的驱动与虚拟化技术分享园地 2646

滑动窗口

7:滑动窗口 查看提交统计提问 总时间限制: 12000ms 内存限制: 65536kB 描述 给定一个长度为n(n 下面是一个例子: 数组是 [1 3 -1 -3 5 3 6 7], k = 3。 窗口位置 最小值 最大值 [1  3  -1] -3  5  3  6  7  -1 3

m0_57375647的博客 1343

手把手教你玩转服务器芯片架构--​​7.1 项目1:基于FPGA的RISC-V软核设计(Verilog实现核心指令执行单元)​

本文介绍了基于FPGA的RISC-V软核设计实践项目。项目采用Verilog实现RV32I指令集核心处理器,包含指令解码、ALU、寄存器堆等关键模块设计,并通过功能仿真验证。在Xilinx Artix-7 FPGA上完成综合与部署,资源利用率控制在5%以内。最后探讨了五级流水线优化、指令集扩展等进阶方案。该实践完整覆盖了从指令集设计、RTL实现到FPGA部署的全流程,可作为学习处理器架构与FPGA开发的典型案例。

MHD0815的博客 173

单调队列及其应用

单调队列(Monotonic Queue)是一种特殊的数据结构,单调队列的特点是其内部元素保持单调性,即要么递增,要么递减。

2301_80295548的博客 1413

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

STM32F407中文手册

STM32f407中文手册 本参考手册面向应用开发人员,提供有关使用 STM32F405xx/07xx、STM32F415xx/17xx、 STM32F42xxx 和 STM32F43xxx 微控制器存储器与外设的完整信息。STM32F405xx/07xx、STM32F415xx/17xx、STM32F42xxx 和 STM32F43xxx 构成一个微 控制器系列,各产品具有不同的存储器大小、封装和外设。有关订购信息以及器件的机械与电气特性,请参见数据手册。有关 ARM Cortex™-M4F 内核的信息,请参见《Cortex™-M4F 技术参考手册》。

单调栈和单调队列应用

1.单调栈 单调栈是指一个栈内部的元素是具有严格单调性的一种数据结构,分为单调递增栈和单调递减栈。 单调栈有两个性质 1.满足从栈顶到栈底的元素具有严格的单调性 2.满足栈的后进先出特性越靠近栈底的元素越早进栈 元素进栈过程 对于一个单调递增栈来说 若当前进栈的元素为 a 如果a &lt; 栈顶元素则直接将a 进栈 如果 a &gt;= 当前栈顶元素则不断将栈顶元素出栈知道满足 a &...

胖亚亚的小酒馆 330

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

单调队列及应用

现在这个从左边开始向右滑动,每次滑动一个单位,求出每次滑动后窗口中的最大值和最小值。从左往右遍历数组,如果队尾元素大于等于当前元素,则将队尾元素出队,知道队列为空或小于为止。单调队列找最大值,如果当前元素的两倍小于队头,则队头标记。显然,当歌曲里的最大值仍比最小值的两倍小时,无论从哪首歌开始,都不会停止。列,因此,遍历这个范围内的数,找到最大值和最小值差最小的数即可。的正方形区域,使得该区域所有数中的最大值和最小值的差最小。方阵的右下角,它的值是这个方阵内数字的最小值。,就会产生负面情绪,立刻停止播放。

jhy20100420zzz的博客 1111

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

单调队列的模板应用

注意讲解单调队列在窗口问题的应用以及优势。

2301_79933754的博客 493

单调栈与单调队列初步应用

一、单调栈 能解决的问题: 单调栈适用于解决以某个值为最大值(最小值)为边界的最大区间问题(划重点) 使用的算法: 如果需要求解以某个值为最大值(最小值)为边界的最大区间,我们可以设想,构造一个单调递减(增)的栈,这样做的理由是单调递减(增)说明一开始的值是栈内的最大值(最小值),如果我需要求某一个值作为边界的最大区间,只需要以这个值为右边界(左边界),然后放心大胆的向左(右)拓展,直到扩展到栈的...

qq_44274276的博客 898

单调队列的思想及应用

单调队列,就是有单调性的队列。

qq_30961125的博客 210

单调队列的实现与应用

                                       单调队列 单调队列引入: 首先看一个例题:   给你一个长度为N的数组,一个长为K的滑动框从最左端滑到最右端,你只可以看到框内的K个数,每次框向右移动一格。请你找出框在各位置的最小值。 样例输入: 8 3 1 3 -1 -3 5 3 6 7 样例输出: -1 -3 -3 -3 3 3 代码实现(已经修改...

jiruliu的博客 1041

单调队列及其LeetCode应用详解

队列(Queue)是另一种操作受限的线性表,只允许元素从队列的一端进,另一端出,因为具有先进先出(FIFO)的特性。 单调队列(Monotonic Queue)是一种特殊的队列,它首先是一个队列,其次队列内部的元素单调递增(递增队列)或者单调递减(递减队列)。 注意:单调队列是基于双端队列(Deque)实现的。 单调队列在算法中的应用在于可以求区间内的最大或者最小值。 // 递增队列 for(int i=0; i<nums.length; i++) { while(!deque.isEmpty()

Steve Wang's blog 671
上一篇: 逆序数
下一篇: kmp代码
HuanTongH
博客等级 码龄12年 7粉丝 110原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值