首页 > 其他分享 >【模板】单调队列 滑动窗口最值

【模板】单调队列 滑动窗口最值

时间:2024-03-23 09:58:41浏览次数:32  
标签:队尾 窗口 队列 int 最小值 出队 最值 模板

Luogu P1886 滑动队列/单调队列

有一个长为 n 的序列 a,以及一个大小为 k 的窗口。现在这个从左边开始向右滑动,每次滑动一个单位,求出每次滑动后窗口中的最大值和最小值。

 

以求最小值为例
f[i]表示以i结尾的窗口中的最小值
f[i]=min(a[j]),i-k+1<=j<=i
暴力算法O(n^2)
for:i=1~n
   for:j=i-k+1~i
       f[i]=min(a[j) 


单调队列:队尾进队出队,队头出队(维护子序列的单调性)

5 7 8 ——> 5 7 ——> 5 ——> 5 6 ——> 5 6 8

1.队尾出队的条件:队列不空且新元素更优,队中旧元素队尾出队
2.每个元素必然从队尾进队一次
3.队头出队的条件:队头元素滑出了窗口
注意:队列中存储元素的下标,方便判断队头出队 


//维护窗口最小值
int h=1,t=0;                             //清空队列
for(int i=1;i<=n;i++) {                  //枚举序列
    while(h<=t&&a[q[t]]>=a[i] t--;       //队尾出队(队列不空且新元素更优)  min(a[i])
    q[++t]=i;                            //队尾入队(存储下标 方便判断队头出队)  j<=i
    if(q[h]<i-k+1) h++;                  //队头出队(队头元素滑出窗口)   i-k+1<=j
    if(i>=k) cout<<a[q[h]]<<" ";         //使用最值
}

每个元素最多进队和出队各一次,时间复杂度为O(n)

#include <bits/stdc++.h>

using namespace std;

const int N=1e6+10;
int a[N],q[N];
int main() {
    ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
    int n,k;cin>>n>>k;
    for(int i=1;i<=n;i++) cin>>a[i];
    //维护窗口最小值
    int h=1,t=0;
    for(int i=1;i<=n;i++) {
        while(h<=t&&a[q[t]]>=a[i]) t--;
        q[++t]=i;
        if(q[h]<i-k+1) h++;
        if(i>=k) cout<<a[q[h]]<<" ";
    }
    cout<<'\n';
    //维护窗口最大值
    h=1,t=0;
    for(int i=1;i<=n;i++) {
        while(h<=t&&a[q[t]]<=a[i]) t--;
        q[++t]=i;
        if(q[h]<i-k+1) h++;
        if(i>=k) cout<<a[q[h]]<<" ";
    }
    return 0;
}

维护最小值就是维护窗口内的升序子序列

维护最大值就是维护窗口内的降序子序列

标签:队尾,窗口,队列,int,最小值,出队,最值,模板
From: https://blog.csdn.net/2301_80405485/article/details/136918740

相关文章

  • 数据结构:详解【栈和队列】的实现
    目录1.栈1.1栈的概念及结构1.2栈的实现1.3栈的功能1.4栈的功能的实现1.5完整代码2.队列2.1队列的概念及结构2.2队列的实现2.3队列的功能2.4队列的功能的实现2.5完整代码1.栈1.1栈的概念及结构栈:一种特殊的线性表,其只允许在固定的一端进行插入和删除......
  • 排序合集模板
    #include<bits/stdc++.h>usingnamespacestd;constintN=1005;inta[N];intt[N];intn;voidbubbleSort(inta[],intn){//冒泡排序://时间复杂度:O(n^2)//是否稳定:是 for(inti=n;i>1;i--){ for(intj=1;j<i;j++){ if(a[j]>a[j+1]){......
  • 常见算法模板
    常见算法快速排序#include<iostream>#include<algorithm>//快速排序voidqsort(inta[],intleft,intright){if(left>=right)return;inti=left-1,j=right+1;intx=a[left+right>>1];while(i<j){doi++;while(a[i]<x);doj--;while(a[j]>......
  • [C++提高编程](一):模板----函数模板
    目录函数模板作用函数模板的语法注意事项普通函数与函数模板的区别普通函数与函数模板的调用规则模板的局限性案例--通用数组选择排序从大到小模板是C++中泛型编程的基础,一个模板就是一个创建类或函数的蓝图或者公式。函数模板作用建立一个通用函数,其函数返回值类型......
  • 异步消息队列Celery
    1.什么是Celery4.4.0|Celery中文手册(celerycn.io)1.1介绍Celery是一个简单、灵活且可靠的,处理大量消息的分布式系统,专注于实时处理的异步任务队列,同时也支持任务调度。Celery的架构由三部分组成,消息中间件(messagebroker),任务执行单元(worker)和任务执行结果存储(tas......
  • C# 根据模板导出Excel
    ///<summary>///导出Excel(使用模板)///</summary>///<returns></returns>[HttpGet]publicIActionResultExportExcelByTemplate(){try{IWorkbookwb=null;vartemplate=Directory.GetCurrentDirectory()+@&q......
  • 【包远程安装运行】SpringBoot+Mysql实现的共享厨房平台+演示视频+开发文档(论文模板)
    今天发布的是由【猿来入此】的优秀学员独立做的一个基于springboot脚手架的共享厨房平台系统,该系统可以实现线上提前预约,线下使用。利用支付宝沙箱来作为支付方式,使该系统更切合实际的表现出实体店线下共享厨房的流程。该系统分为前台和后台。主要实现了除脚手架功能以外下......
  • 【包远程安装运行】SpringBoot+Mysql实现的美食分享菜谱制作平台+演示视频+开发文档(
    今天发布的是由【猿来入此】的优秀学员独立做的一个基于springboot脚手架的美食分享菜谱制作平台系统,该系统分为前台和后台,多用户分享平台。主要实现了除脚手架功能以外下面是系统的功能:前台普通用户:注册、登录、首页、美食家列表、菜谱列表、社区论坛、资讯列表、个人中......
  • C++ Stacks(堆栈) 和 Queues(队列)的基本用法
    一、栈1.栈的定义        栈(stack)是限定仅在表的一端进行插入和删除操作的线性表,允许插入和删除的一端称为栈顶(stacktop),另一端称为栈底(stackbottom),不含任何数据元素的栈称为空栈。        如图1-1所示,栈中有三个元素,插入元素(也称为入栈、进栈、压......
  • 4.1、模板
    模板1、模板的概念模板就是建立通用的模具,大大提高复用性。模板的特点:1.模板不可以直接使用,它只是一个框架。2.模板的通用并不是万能的。2、模板函数C++另一种编程思想称为:泛型编程,主要利用的技术就是模板。C++提供两种模板机制:函数模板和类模板2.1函数模板语法函数......