单调栈 详解+例题

news/2024/9/22 14:16:19

昨天打 AT 碰到了一道单调栈的题,于是来复习一下

单调栈

栈内元素单调性
单调递增栈单调递减栈

实现:

举个例子:

假设入栈序列为

1 4 2 8 9 3

要模拟一个单调递增栈:

  • \(i=1\) 时,栈为空,\(1\) 入栈后仍然保持单调性,将 \(1\) 入栈;
  • \(i=2\) 时,栈顶元素为 \(1\)\(4\) 入栈后仍然保持单调性,将 \(4\) 入栈;
  • \(i=3\) 时,栈顶元素为 \(4\)\(2\) 入栈后不满足单调性,\(4\) 出栈。
    此时 \(2\) 入栈后能保持单调性,\(2\) 入栈;
  • \(i=4\) 时,栈顶元素为 \(2\)\(8\) 入栈后仍然保持单调性,将 \(8\) 入栈;
  • \(i=5\) 时,栈顶元素为 \(8\)\(9\) 入栈后仍然保持单调性,将 \(9\) 入栈;
  • \(i=6\) 时,栈顶元素为 \(9\)\(3\) 入栈后不满足单调性,\(9\)出栈。
    这时栈顶元素为 \(8\)\(3\) 入栈后不满足单调性,\(8\)出栈。
    此时 \(3\) 入栈后能保持单调性,\(3\) 入栈;

代码:

stack<int>st;//栈里面存下标 for(int i=1;i<=n;i++)
{while(!st.empty()&&a[st.top()]>a[i])//a[i]入栈后不是单调递增的st.pop();//出栈……//更新答案 st.push(i); 
}

那它有什么用呢?

洛谷模板题

题目大意:

给你一个数列 \(a\),求数列中第 \(i\) 个元素后面第一个大于它的元素的下标

思路:

  • 思路一:建立一个单调递减的栈
    按照顺序入栈
    如果一个数入栈就不满足单调递减了,证明这个数是目前栈顶的元素后面第一个大于它的元素的下标
    记录答案
  • 思路二:建立一个单调递减的栈
    倒序入栈
    如果一个数入栈就不满足单调递减了,栈顶出栈
    最后栈顶就是此时入栈元素后面第一个大于它的元素的下标
    记录答案

完整代码:

思路一:

#include<bits/stdc++.h>using namespace std;int n;
int a[3000100];
int f[3000100];
stack<int>st;int main()
{cin>>n;for(int i=1;i<=n;i++){cin>>a[i];}for(int i=1;i<=n;i++){while(!st.empty()&&a[st.top()]<a[i]){f[st.top()]=i;st.pop();}st.push(i);}for(int i=1;i<=n;i++){cout<<f[i]<<(i!=n?" ":"\n");}return 0;
}

思路二:

#include<bits/stdc++.h>using namespace std;int n;
int a[3000100];
stack<int>st;
int f[3000100];int main()
{cin>>n;for(int i=1;i<=n;i++){cin>>a[i];} for(int i=n;i>=1;i--){while(!st.empty()&&a[st.top()]<=a[i]) st.pop();if(!st.empty())f[i]=st.top();//这里要特别判断一下是否为空else f[i]=0;st.push(i);}for(int i=1;i<=n;i++){cout<<f[i]<<(i!=n?" ":"\n");}return 0;
}

例题:

https://www.luogu.com.cn/problem/P2866
https://www.luogu.com.cn/problem/P2947
https://atcoder.jp/contests/abc372/tasks/abc372_d

完结撒花!

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

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

相关文章

win10x64位+nmake编译geos3.7.1

说明:使用nmake进行编译,最新的geos3.13似乎已经不能用nmake进行编译了,不过3.7.1已经够用了。 1、 解压geos-3.7.1,定位到根目录下的namke.opt文件,这个文件控制着nmake编译的一些参数。 2、 打开nmake.opt,找到如下片段: ###########################################…

Nuxt Kit API :路径解析工具

title: Nuxt Kit API :路径解析工具 date: 2024/9/22 updated: 2024/9/22 author: cmdragon excerpt: 摘要:本文介绍了Nuxt Kit中用于解析路径的API工具,包括resolvePath、resolveAlias、findPath和createResolver。这些工具助力开发者处理模块路径、别名、文件扩展名,提…

使用GPU 加速 Polars:高效解决大规模数据问题

Polars 最近新开发了一个可以支持 GPU 加速计算的执行引擎。这个引擎可以对超过 100GB 的数据进行交互式操作能。本文将详细讨论 Polars 中DF的概念、GPU 加速如何与 Polars DF协同工作,以及使用新的 CUDA 驱动执行引擎可能带来的性能提升。 https://avoid.overfit.cn/post/b…

我的网站集成ElasticSearch初体验

最近,我给我的网站(https://www.xiandanplay.com/)尝试集成了一下es来实现我的一个搜索功能,因为这个是我第一次了解运用elastic,所以如果有不对的地方,大家可以指出来,话不多说,先看看我的一个大致流程 这里我采用的sdk的版本是Elastic.Clients.Elasticsearch, Ver…

Flipper Zero极客的便携式多功能工具设备

官网:Flipper Zero — 极客的便携式多功能工具设备 Flipper Zero是近两年比较热门的硬件工具,官方固件主要涵盖的功能为Sub-Ghz,125kHz,NFC,红外。 基本信息资料都可以在官方网站找到比较详细的文档解释。本篇主要是一个基础入门,这系列也是给自己学习此硬件一个上手研究…

C盘扩容免费工具

1.diskgenius 下载 https://www.diskgenius.cn/download.php 解压即可使用,无需安装 2.下载 安装Windows_PE环境 https://www.diskgenius.cn/help/windows_aik_adk_installnotes.php?Version=0A000000&Build=22631&Lang=936 官方软件,安全五毒 3.运行diskgenius ,点…

Leetcode 2464. 有效分割中的最少子数组数目

1.题目基本信息 1.1.题目描述 给定一个整数数组 nums。 如果要将整数数组 nums 拆分为 子数组 后是 有效的,则必须满足: 每个子数组的第一个和最后一个元素的最大公约数 大于 1,且 nums 的每个元素只属于一个子数组。 返回 nums 的 有效 子数组拆分中的 最少 子数组数目。如果…

debian 系统服务器搭建

在VMWare中安装Debian12.5虚拟机后, 需要开始进行一些设置:1. 先设置网络模式为桥接模式, 这样和主机在同一个局域网,方便后续ssh连接 2. 第1步设置后,重启Debian,登录后, 查看IP和Mac地址, 192.168.31.16,00:0c:29:6c:31:e6 3. 设置路由器,固定IP: 192.168.31.105。 …