单调队列算法 - 滑动窗口问题(常见模型:找出滑动窗口中的最大值/最小值)

news2024/11/24 3:45:56

欢迎观看我的博客,如有问题交流,欢迎评论区留言,一定尽快回复!(大家可以去看我的专栏,是所有文章的目录)
文章字体风格:
红色文字表示:重难点✔
蓝色文字表示:思路以及想法✔
 
如果大家觉得有帮助的话,感谢大家帮忙
点赞!收藏!转发!

单调队列算法 - 滑动窗口问题

  • 1. 单调队列模板
  • 例题 - 滑动窗口
        • 代码关键

1. 单调队列模板

常见模型:找出滑动窗口中的最大值/最小值
int hh = 0, tt = -1;
for (int i = 0; i < n; i ++ )
{
    while (hh <= tt && check_out(q[hh])) hh ++ ;  // 判断队头是否滑出窗口
    while (hh <= tt && check(q[tt], i)) tt -- ;
    q[ ++ tt] = i;
}

例题 - 滑动窗口

在这里插入图片描述
首先,看完这个题,我自己的一个想法是

  1. 最大值和最小值分两次求
  2. 先找到前k个中最小的一个,然后在k+1开始遍历
  3. 如果前k个中最小的是窗口中滑出的那一个,则在min+1到i,重新找到一个新的最小值,然后再次比较
  4. 如果不是的话。。。。具体逻辑代码就体现出来了
#include<iostream>
using namespace std;

const int N = 1e6+10;
int q[N],tt,hh = 1;
int a[N];

int main()
{
    int n,k;
    cin >> n >> k;
    int min = 1;
    for(int i = 1; i <= n; i++)
        cin >> a[i];
    
    for(int i = 1; i <= k; i++)
    {
        if(a[min] > a[i])
            min = i;
    }
    q[hh++] = a[min];
    printf("%d ",q[hh-1]);
    for(int i = k+1; i <= n; i++)
    {
        if(min+k<=i)
        {
            int kk = min+1;
            min+=1;
            while(kk <= i)
            {
                 if(a[min] > a[kk])
                 {
                     min = kk;
                 }
                 kk++;
            }
            q[hh++] = a[min];
            printf("%d ",q[hh-1]);
        }
        else if(a[i] <= a[min])
        {
            q[hh++] = a[i];
            min = i;
            printf("%d ",q[hh-1]);
        }
        else
        {
            q[hh++] = a[min];
            printf("%d ",q[hh-1]);
        }
    }
    
    cout << endl;
    hh = 1,tt = 0;
    min = 1;
    for(int i = 1; i <= n; i++)
        cin >> a[i];
    
    for(int i = 1; i <= k; i++)
    {
        if(a[min] < a[i])
            min = i;
    }
    q[hh++] = a[min];
    printf("%d ",q[hh-1]);
    for(int i = k+1; i <= n; i++)
    {
        if(min+k<=i)
        {
            int kk = min+1;
            min+=1;
            while(kk <= i)
            {
                 if(a[min] < a[kk])
                 {
                     min = kk;
                 }
                 kk++;
            }
            q[hh++] = a[min];
            printf("%d ",q[hh-1]);
        }
        else if(a[i] >= a[min])
        {
            q[hh++] = a[i];
            min = i;
            printf("%d ",q[hh-1]);
        }
        else
        {
            q[hh++] = a[min];
            printf("%d ",q[hh-1]);
        }
    }
    
    return 0;
}

代码关键

这个代码 超时了
问题就出现在了第3条中
当最小值滑出窗口,我们不应该重新遍历找最小值,如果可以直接找到最小值,或者说减少寻找次数最好

所以我们就采取了另一种方式
创建一个具有单调性的队列,
每次判断的时候,如果i对应的值,满足队列的单调性就入队列
如果不满足,那么就从队尾往前更改队列,使得队列具有单调性,且还具有一定的顺序性,

有个关键问题:单调队列存储的是 数值还是数值的角标?
如果存储的是数值的话,但最值滑出窗口,我们更新最值,但是我们就不能有效得到最值的角标进而去判断下一个最值什么时候滑出窗口。
所以我们应该存储的是角标

#include <iostream>

using namespace std;

const int N = 1000010;

int a[N], q[N];

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

    int hh = 0, tt = -1;
    for (int i = 0; i < n; i ++ )
    {
        if (hh <= tt && i - k + 1 > q[hh]) hh ++ ;

        while (hh <= tt && a[q[tt]] >= a[i]) tt -- ;
        q[ ++ tt] = i;

        if (i >= k - 1) printf("%d ", a[q[hh]]);
    }

    puts("");

    hh = 0, tt = -1;
    for (int i = 0; i < n; i ++ )
    {
        if (hh <= tt && i - k + 1 > q[hh]) hh ++ ;

        while (hh <= tt && a[q[tt]] <= a[i]) tt -- ;
        q[ ++ tt] = i;

        if (i >= k - 1) printf("%d ", a[q[hh]]);
    }

    puts("");

    return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/91066.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

ASEMI肖特基二极管MBR10100FCT图片,MBR10100FCT大小

编辑-Z ASEMI肖特基二极管MBR10100FCT参数&#xff1a; 型号&#xff1a;MBR10100FCT 最大重复峰值反向电压&#xff08;VRRM&#xff09;&#xff1a;100V 最大RMS电桥输入电压&#xff08;VRMS&#xff09;&#xff1a;70V 最大直流阻断电压&#xff08;VDC&#xff09;…

SpringBoot整合Druid数据源

SpringBoot整合Druid数据源1.使用Druid数据源2.完整的Druid配置3.为 DruidDataSource 绑定全局配置文件中的参数4.配置Druid数据源监控5.配置 filter 过滤器1.使用Druid数据源 <!-- https://mvnrepository.com/artifact/com.alibaba/druid --> <dependency><gr…

方差分析 / 主成分分析 / 因子分析 / 聚类分析

一.方差分析 水平&#xff1a;因素的不同状态&#xff0c;分组是按照因素的不同水平划分的 因变量&#xff1a;在分组试验中&#xff0c;对试验对象所观测记录的变量&#xff0c;它是受各因素影响的变量 常见的方差分析类型&#xff1a;单因素方差分析&#xff0c;多因素方差…

RK3568平台开发系列讲解(调试篇)如何跟踪系统事件

🚀返回专栏总目录 文章目录 一、ltrace二、strace三、ptrace沉淀、分享、成长,让自己和他人都能有所收获!😄 📢本文我们要介绍 Linux 上两个非常有用的工具:ltrace 和 strace。在分析软件的运行过程、调试疑难 Bug、执行性能分析和调优等方面,它们都是非常有用的辅助…

肠道核心菌属——优/真杆菌属(Eubacterium),你为什么要关心它?

谷禾健康 Eubacterium 通常翻译为真杆菌属或优杆菌属 Eubacterium&#xff0c;革兰氏阳性细菌&#xff0c;属于真杆菌科&#xff0c;厚壁菌门。 Eubacterium 是在健康人结肠中发现的一种重要的肠道细菌&#xff0c;它是人类肠道微生物群的核心菌属之一&#xff0c;并显示…

SPI通信协议详解

一&#xff0c;SPI的简介 SPI&#xff0c;是英语Serial Peripheral interface的缩写&#xff0c;顾名思义就是串行外围设备接口。是Motorola首先在其MC68HCXX系列处理器上定义的。SPI接口主要应用在 EEPROM&#xff0c;FLASH&#xff0c;实时时钟&#xff0c;AD转换器&#xff…

【力扣刷题】预测赢家

&#x1f517; 题目链接 题目描述 给你一个整数数组 nums 。玩家 1 和玩家 2 基于这个数组设计了一个游戏。 玩家 1 和玩家 2 轮流进行自己的回合&#xff0c;玩家 1 先手。开始时&#xff0c;两个玩家的初始分值都是 0 。每一回合&#xff0c;玩家从数组的任意一端取一个数…

leetcode热题HOT100汇总——持续更新中

文章目录前言1. 两数之和2. 两数相加3.无重复字符的最长子串4. 寻找两个正序数组的中位数5. 最长回文子串10. 正则表达式匹配11. 盛最多水的容器15. 三数之和17. 电话号码的字母组合19. 删除链表的倒数第 N 个结点20. 有效的括号21. 合并两个有序链表前言 为了学习本文捋顺lee…

再多学一点Spring之过滤器与拦截器的区别

学习和使用Spring这么久了&#xff0c;我们都用过过滤器和拦截器&#xff0c;但是真要被问到过滤器和拦截器有什么区别&#xff0c;我又一脸懵逼了&#xff0c;回答不上来。今天我们就来学习一下&#xff0c;过滤器和拦截器。 过滤器 通过实现javax.servlet.Filter接口来自定义…

网站被篡改 收录一些非本网站快照跳转如何解决

在实际的网站运营维护过程中&#xff0c;经常发生网站被HACK攻击等情况&#xff0c;尤其网站的标题被篡改为中文关键词<title>&#xff0c;使得网站在百度搜索的索引结果非常的明显&#xff0c;直接在浏览器里打开网站&#xff0c;用肉眼看到的是未被篡改的首页标题。根据…

计算机学徒等级划分

目录 第一级&#xff1a;菜鸟级 第二级&#xff1a;新手级 第三级&#xff1a;入门级 第四级&#xff1a;精通级 第五级&#xff1a;巅峰级 第一级&#xff1a;菜鸟级 概述&#xff1a;你问他计算机是干什么的&#xff1f;他说&#xff1a;“打游戏的&#xff0c;看电影的…

地下水监测系统的构成,优势是什么?

平升电子地下水监测系统由地下水自动监测站监测设备和监测中心平台软件组成。监测设备自动采集、存储地下水水位、水温、水量、水质数据&#xff0c;通过4G/NB-IoT/北斗无线通信网络定时上报至省/市/县级监测中心平台&#xff0c;平台自动接收和存储数据&#xff0c;并对地下水…

排查 Edge WebView2 在某个设备上不出图像的问题

我们在 Windows 应用内嵌入 Edge WebView2&#xff0c;来展示部分用网页实现的界面。总得来说还是不错的&#xff0c;比如&#xff1a; 渲染很快&#xff0c;基本上内置网页100毫秒以内控件样式很清爽&#xff0c;没有多余界面开发需要调用的 API 也不多 但是最近在某个用户那…

2022年山东最新建筑施工架子工(建筑特种作业)模拟题库及答案

百分百题库提供特种工&#xff08;架子工&#xff09;考试试题、特种工&#xff08;架子工&#xff09;考试预测题、特种工&#xff08;架子工&#xff09;考试真题、特种工&#xff08;架子工&#xff09;证考试题库等,提供在线做题刷题&#xff0c;在线模拟考试&#xff0c;助…

21天学Python --- 打卡12:python执行jar包

21天学Python --- 打卡12:Python执行jar包1. Subprocess1.1 Method1.2 Execure Jar2. Jpype2.1 Install2.2 Execute Simple Jar2.2.1 Java Code2.2.2 Python Code2.3 Execute Maven Jar3. Awakening1. Subprocess subprocess 是 Python 2.4 中新增的一个模块 1.1 Method subpro…

第二证券|医药板块短期轮动加快 机构看好后市机会

作为现在商场行情继续性最强的职业板块&#xff0c;医药股昨日早盘呈现回调&#xff0c;午后继续反弹&#xff0c;体现出较强的承接动能。机构以为&#xff0c;本轮新冠医治概念主线行情或仍将延续&#xff0c;但个股或将继续分解。 在本轮反弹行情中&#xff0c;医药板块表现较…

postgres 源码解析 44 btree插入流程 btinsert

基于前两篇对btree的基础介绍&#xff0c;本文将从源码角度讲解btree的插入流程&#xff0c;相关至内容见&#xff1a; postgres源码解析41 btree索引文件的创建–1 postgres源码解析42 btree索引文件的创建–2 数据结构 /** BTStackData -- As we descend a tree, we push t…

干货 | 鸿翼&深信服之内容安全3大应用场景实践

随着企业数字化转型的推进&#xff0c;在企业内容管理层面&#xff0c;面临着数据爆发式增长&#xff0c;内容安全合规、海量非结构化数据分散存储&#xff0c;业务系统重建数据难以整合&#xff0c;无法统一管理等问题。 在数据安全层面&#xff0c;随着新威胁层出不穷&#…

Docker的CICD

&#x1f38f;⭕引言 回顾使用docker进行项目部署的步骤&#xff1a; 将项目通过maven进行编译打包将文件上传到指定的服务器中将war包放到tomcat的目录中通过Dockerfile将Tomcat和war包转成一个镜像&#xff0c;由DockerCompose的docker-compose.yml去运行容器 以上操作&#…

frp内网穿透详细安装步骤以及使用

frp是一款内网穿透工具&#xff0c;首先要一台服务器用作服务端&#xff08;Linux&#xff09;&#xff0c;将自己的(WIN10)电脑用作客户端&#xff0c;我将通俗的讲解详细的安装以及使用过程&#xff0c;废话不多直接开始。 Linux要开放 7000 7500 9600端口&#xff0c;一…