【算法】单调队列

news2024/12/28 20:44:04

一、什么是单调队列

单调队列是一种数据结构,其特点是队列中的元素始终保持单调递增或递减,主要用于维护队列中的最小值或最大值

不同于普通队列只能从队头出队、队尾入队,单调队列为了维护其特征,还允许从队尾出队

不管怎么向单调队列中添加元素或删除元素,其单调性始终不变。这是如何做到的呢?我们用一道例题来说明

二、如何使用单调队列

2.1 滑动窗口问题

滑动窗口问题是单调队列的典型应用场景

简单来说,一个长度固定的窗口从序列开始一步步移动到结尾,我们要得到这个窗口每一步移动中其内部的最大值和最小值。

这个问题很简单,如果我们使用一个单调队列,窗口每次移动就将新元素入队,让其内部的元素保持单调递增,那么队头元素就是窗口的最小值,求最大值则保持单调递减即可

那我们该如何维护一个单调队列呢?首先来讲讲单调队列的思想

2.2 单调队列的思想

我们以上面例题中给出的序列 {1,3,-1,-3,5,3,6,7} 为例,窗口大小为3,单调队列大小和窗口一致

窗口从头开始向后移动,首先是1入队,然后是3入队,到这里单调队列内部都保持单调递增,于是我们不作处理

窗口继续向后移动,接下来是-1入队。但是-1入队后就打破了单调队列的单调性了,所以我们需要进行一些操作维护其单调性

因为我们选择保持队列单调递减,所以当有更小的元素要从队尾入队时,我们要把它前面所有比它更大的元素全都先从队尾出队

也就是说,当准备入队的元素更优时,我们需要先将前面造成干扰的元素出队,再将新元素入队。

此时,窗口已经完整的进入序列中了,可以开始拿到最值,此时单调队列的队头元素就是窗口中的最小值

窗口滑动,接下来-3准备入队。和前面的步骤一样,先将-1从队尾出队,然后-3入队

得到此时窗口最小值-3 

窗口滑动,接下来5正常入队

得到此时窗口最小值-3

窗口滑动,接下来3准备入队,和前面的步骤一样,先将5从队尾出队,然后3入队

得到此时窗口最小值-3

窗口滑动,接下来6正常入队

但是!此时单调队列中的-3已经滑出窗口范围了,需要出队

得到此时窗口最小值3

窗口滑动,接下来7正常入队

得到此时窗口最小值3

这就是单调队列完整的思想,如果要求窗口每个时刻的最大值,则将单调队列保持单调递减即可

2.3 实际解题过程

明白了单调队列的思想后,我们还需要学会如何在实际解题时使用它

在上面的例题中,我们可以用一个数组模拟单调队列,用两个下标 h 和 t 来维护队头和队尾

另外一个数组存储目标序列,len 表示窗口长度,i 表示窗口的右侧,则 i - len + 1就是窗口的左侧。通过i++就可以实现窗口滑动的效果

我们在单调队列中存储元素在原序列中的下标,这样做是为了便于判断一个元素仍在单调队列中但已经滑出窗口的情况(如果该元素的下标小于窗口左侧则说明已经滑出窗口,则出队)

用下标维护队列头尾的目的:采用伪删除法,将 t-- 就能达到队尾出队的效果,h++就能达到队头出队的效果

大概思路都讲完了,这里直接放出例题的代码

#include <iostream>
using namespace std;

const int N = 1000010;

int n, k;
int a[N];
int q[N];

void winmin() //求窗口最小值
{
    int h = 1, t = 0; //h是队头,t是队尾,队列初始为空
    for(int i = 1;i <= n;i++) //i为窗口右端,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 << endl;
}

void winmax() //求窗口最大值
{
    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 << endl;
}

int main()
{
    cin >> n >> k;
    for(int i = 1;i <= n;i++) //注意这里元素是从下标为1处开始存储
        cin >> a[i];
    winmin();
    winmax();
    return 0;
}

完.

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

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

相关文章

【学习笔记】4、组合逻辑电路(上)

数字电路的分类&#xff1a;组合逻辑电路&#xff0c;时序逻辑电路。本章学习组合逻辑电路。 4.1 组合逻辑电路的分析 给定的逻辑电路&#xff0c;确定其逻辑表达式&#xff0c;列出真值表&#xff0c;得到简化后的逻辑表达式&#xff0c;分析得到其功能。 3位奇校验电路 &…

OSPF.综合实验

1、首先将各个网段基于172.16.0.0 16 进行划分 1.1、划分为4个大区域 172.16.0.0 18 172.16.64.0 18 172.16.128.0 18 172.16.192.0 18 四个网段 划分R4 划分area2 划分area3 划分area1 2、进行IP配置 如图使用配置指令进行配置 ip address x.x.x.x /x 并且将缺省路由…

MQTT——Mosquitto使用(Linux订阅者+Win发布者)

前提&#xff1a;WSL&#xff08;Ubuntu22&#xff09;作为订阅者&#xff0c;本机Win10作为发布者。 1、Linux安装Mosquitto 命令行安装。 sudo apt-get install mosquitto 以上默认只安装了mosquitto的服务&#xff0c;不带测试客户端工具mosquitto_sub和mosquitto_pub。如…

持续学习中避免灾难性遗忘的Elastic Weight Consolidation Loss数学原理及代码实现

训练人工神经网络最重要的挑战之一是灾难性遗忘。神经网络的灾难性遗忘&#xff08;catastrophic forgetting&#xff09;是指在神经网络学习新任务时&#xff0c;可能会忘记之前学习的任务。这种现象特别常见于传统的反向传播算法和深度学习模型中。主要原因是网络在学习新数据…

全网最详细单细胞保姆级分析教程(二) --- 多样本整合

上一节我们研究了如何对单样本进行分析,这节我们就着重来研究一下如何对多样本整合进行研究分析! 1. 导入相关包 library(Seurat) library(tidyverse) library(patchwork)2. 数据准备 # 导入单样本文件 dir c(~/Desktop/diversity intergration/scRNA_26-0_filtered_featur…

基于TCP的在线词典系统(分阶段实现)(阻塞io和多路io复用(select)实现)

1.功能说明 一共四个功能&#xff1a; 注册 登录 查询单词 查询历史记录 单词和解释保存在文件中&#xff0c;单词和解释只占一行, 一行最多300个字节&#xff0c;单词和解释之间至少有一个空格。 2.功能演示 3、分阶段完成各个功能 3.1 完成服务器和客户端的连接 servic…

WAF基础介绍

WAF 一、WAF是什么&#xff1f;WAF能够做什么 二 waf的部署三、WAF的工作原理 一、WAF是什么&#xff1f; WAF的全称是&#xff08;Web Application Firewall&#xff09;即Web应用防火墙&#xff0c;简称WAF。 国际上公认的一种说法是&#xff1a;Web应用防火墙是通过执行一…

电表及销售统计Python应用及win程序2

接着上一篇给代码添加了表格功能&#xff0c;方便更好的处理数据。 import json import os from datetime import datetime from tkinter import * from tkinter import messagebox from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg from matplotlib.figure …

JAVA设计模式>>结构型>>适配器模式

本文介绍23种设计模式中结构型模式的适配器模式 目录 1. 适配器模式 1.1 基本介绍 1.2 工作原理 1.3 适配器模式的注意事项和细节 1.4 类适配器模式 1.4.1 类适配器模式介绍 1.4.2 应用实例 1.4.3 注意事项和细节 1.5 对象适配器模式 1.5.1 基本介绍 1.5.2 …

visual studio 2019版下载以及与UE4虚幻引擎配置(过程记录)(官网无法下载visual studio 2019安装包)

一、概述 由于需要使用到UE4虚幻引擎&#xff0c;我使用的版本是4.27版本的&#xff0c;其官方默认的visual studio版本是2019版本的&#xff0c;相应的版本对应关系可以通过下面的官方网站对应关系查询。https://docs.unrealengine.com/4.27/zh-CN/ProductionPipelines/Develo…

java实现资产管理系统图形化用户界面

创建一个&#x1f495;资产管理系统的GUI&#xff08;图形用户界面&#xff09;❤️画面通常需要使用Java的Swing或者JavaFX库。下面我将提供一个简单的资产管理系统GUI的示例代码&#xff0c;使用Java Swing库来实现。这个示例将包括一个主窗口&#xff0c;一个表格来显示资产…

捷配笔记-如何设计PCB板布线满足生产标准?

PCB板布线是铺设连接各种设备与通电信号的路径的过程。PCB板布线是铺设连接各种设备与通电信号的路径的过程。 在PCB设计中&#xff0c;布线是完成产品设计的重要步骤。可以说&#xff0c;之前的准备工作已经为它做好了。在整个PCB设计中&#xff0c;布线设计过程具有最高的极限…

Web浏览器通过串口读取RFID卡号js JavaScript

本示例使用的读卡器&#xff1a;USB转RS232COM虚拟串口RFID读卡器主动读卡Web浏览器Andro、Linux-淘宝网 (taobao.com) <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"…

翁恺-C语言程序设计-05-3. 求a的连续和

05-3. 求a的连续和 输入两个整数a和n&#xff0c;a的范围是[0,9]&#xff0c;n的范围是[1,8]&#xff0c;求数列之和S aaaaaa…aaa…a&#xff08;n个a&#xff09;。如a为2、n为8时输出的是222222…22222222的和。 输入格式&#xff1a; 输入在一行中给出两个整数&#xf…

深入了解 MySQL 的 EXPLAIN 命令

一、什么是 EXPLAIN 命令&#xff1f; EXPLAIN 命令用于显示 MySQL 如何执行某个 SQL 语句&#xff0c;尤其是 SELECT 语句。通过 EXPLAIN 命令&#xff0c;可以看到查询在实际执行前的执行计划&#xff0c;这对于优化查询性能至关重要。 二、EXPLAIN 的基本用法 要使用 EXP…

【算法篇】KMP算法,一种高效的字符串匹配算法

我们今天了解一个字符串匹配算法-KMP算法&#xff0c;内容难度相对来说较高&#xff0c;建议先收藏再细品&#xff01;&#xff01;&#xff01; KMP算法的基本概念 KMP算法是一种高效的字符串匹配算法&#xff0c;由D.E.Knuth&#xff0c;J.H.Morris和V.R.Pratt提出的&#…

Cxx Primer-CP-2

开篇第一句话足见作者的高屋建瓴&#xff1a;类型决定程序中数据和操作的意义。随后列举了简单语句i i j;的意义取决于i和j的类型。若它们都是整形&#xff0c;则为通常的算术意义。若它们都为字符串型&#xff0c;则为进行拼接操作。若为用户自定义的class类型&#xff0c;则…

《Linux系统编程篇》Visual Studio Code配置下载,中文配置,连接远程ssh ——基础篇

引言 vscode绝对值得推荐&#xff0c;非常好用&#xff0c;如果你能体会其中的奥妙的话。 工欲善其事&#xff0c;必先利其器 ——孔子 文章目录 引言下载VS Code配置VS Code中文扩展连接服务器 连接服务器测试确定服务器的IP地址VS code 配置ssh信息选择连接到主机选择这个添…

K8s学习笔记1-搭建k8s集群

本次使用kubeadm方式&#xff0c;部署1.23.17版本 安装包百度云盘地址&#xff1a; 链接&#xff1a;https://pan.baidu.com/s/1UrIotP253DoyDIYB7G1C0Q 提取码&#xff1a;8q6a 集群所需虚拟机环境 主机名称IP资源harbor10.0.0.2301c2gmaster10.0.0.2312c4gworker110.0.0…

全新UI自助图文打印系统源码(含前端小程序源码 PHP后端 数据库)

最新自助图文打印系统和证件照云打印小程序源码PHP后端&#xff0c;为用户用户自助打印的服务&#xff0c;包括但不限于文档、图片、表格等多种格式的文件。此外&#xff0c;它们还提供了诸如美颜、换装、文档打印等功能&#xff0c;以及后台管理系统&#xff0c;方便管理员对打…