单调栈---基础数据结构与算法

news2024/10/7 16:20:44

简介

栈 (stack) 又名堆栈,是一种数据结构,向一个栈插入新元素又称作进栈、入栈或压栈,从一个栈删除元素又称作出栈或退栈。

栈是一种只允许在表尾进行插入和删除操作的线性表,也就是我们所说的后进先出,我们把栈想象成往一个有底的桶中放铁饼,你从桶中拿铁饼,只能拿到最上边的,放铁饼也只能在最上边开始放,如图

栈的实现分两种,数组模拟和链表实现,这里用数组模拟

栈的数组模拟

如果学过了链表,那就对栈的实现很容易上手,甚至只需要看一眼就能够领悟。

const int N =100010;
int stk[N],tt; //tt是栈顶的下标

//栈的插入操作 下标从1开始被使用
stk[++tt] = x ; 

//栈的弹出操作
--tt;

//判断栈是否为空
if(tt>0) not empty //不为空
else empty //为空

//取栈顶元素
stk[tt];

 这里大概了解了栈,那单调栈只不过是栈内元素呈单调性的栈,可能是单调递增,也可能是单调递减。

栈的主要应用场景:找出一个序列中每个数左/右边离它最近的比它大/小的数。

这里来一道题目,快速上手>

题目

给定一个长度为 N 的整数数列,输出每个数左边第一个比它小的数,如果不存在则输出 −1。

输入格式
第一行包含整数 N,表示数列长度。
第二行包含 N 个整数,表示整数数列。

输出格式
共一行,包含 N 个整数,其中第 i 个数表示第 i 个数的左边第一个比它小的数,如果不存在则输出 −1。

数据范围
1≤N≤10^5
1≤数列中元素≤10^9

输入样例:
 

5
3 4 2 7 5

输出样例:
 

-1 3 -1 2 2

输出解释:

3的左边没有比它小的数 输出-1

4的左边比它小的数是3 输出3

2的左边没有比它小的数 输出-1

7的左边比它小的数并且最近的是2 输出2

5的左边比它小的数并且最近的是2 输出2

暴力解法

我们首先想到的暴力算法是,我们要求第 i 个数左边比它小的数并且离它最近,那就是从 i-1 个数开始,向左边遍历,直到找到。

那代码应该这么写

for(int i = 0 ; i < n ; i++ )
{
    for( int j = i - 1 ; j >= 0 ; j-- )
    { 
        if( a[j] <= a[i] )
        {
            printf("%d ",a[j]);
            break;
        }
    }
    //
}

我们观察,暴力做法中可以有什么性质可以减少步骤?

如果有一个数的左边某个数 x 比它还大,那么在这题中 这个x永远都不会被考虑到

例如 a[x]  >=  a[y] 并且 x< y 那么 a[x] 就可以被删去,如图

图中存在这样逆序的点,当我们将所有逆序的点删除了,就得到了

这时,我们只需要将我们的 a[i] 依次与 stk[4]、stk[3]、stk[2] 、stk[1]进行比较(找到小于a[i]的)就可以得出答案

好,这里看代码领悟一下

单调栈解法

#include <iostream>
using namespace std;

const int N = 100010;
int stk[N], tt ;

int main() 
{
    int n;
    scanf("%d", &n);
    while (n--) 
    {
        int x;
        scanf("%d", &x);
        while (tt && stk[tt] >= x) tt--; //当栈中存在元素并且栈顶元素大于等于x时,从栈中弹出栈顶元素
        if (tt) printf("%d ", stk[tt]);//当存在栈顶元素小于x时,将此栈顶元素输出
        else printf("-1 ");  //当未在栈中查找到小于x的元素时,栈中所有元素均被弹出,此时栈为空,输出-1
        stk[++tt] = x; //将x插入到栈顶 
    }

    return 0;
}

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

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

相关文章

软件测试工程师经典面试题,金九银十可以跳槽了。

大家好&#xff0c;前两天跟朋友感慨&#xff0c;今年的铜九铁十、裁员、导致好多人都没拿到offer&#xff01;现在互联网大厂终于迎来了应届生集中求职季。 对于想跳槽的职场人来说&#xff0c;绝对是个找工作的好时机。这时候&#xff0c;很多高薪技术岗、管理岗的缺口和市场…

想要精通算法和SQL的成长之路 - 并查集的运用和案例(省份数量)

想要精通算法和SQL的成长之路 - 并查集的运用 前言一. 并查集的使用和模板1.1 初始化1.2 find 查找函数1.3 union 合并集合1.4 connected 判断相连性1.5 完整代码 二. 运用案例 - 省份数量 前言 想要精通算法和SQL的成长之路 - 系列导航 一. 并查集的使用和模板 先说一下并查集…

记住这份软件测试八股文还怕不能拿offer?你值得拥有

前言 2023秋招即将来临&#xff0c;很多同学会问软件测试面试八股文有必要背吗&#xff1f; 我的回答是&#xff1a;很有必要。你可以讨厌这种模式&#xff0c;但你一定要去背&#xff0c;因为不背你就进不了大厂。 国内的互联网面试&#xff0c;恐怕是现存的、最接近科举考试…

计算机竞赛 车道线检测(自动驾驶 机器视觉)

0 前言 无人驾驶技术是机器学习为主的一门前沿领域&#xff0c;在无人驾驶领域中机器学习的各种算法随处可见&#xff0c;今天学长给大家介绍无人驾驶技术中的车道线检测。 1 车道线检测 在无人驾驶领域每一个任务都是相当复杂&#xff0c;看上去无从下手。那么面对这样极其…

【MySQL】表的约束(一)

文章目录 为什么要有约束一. 空属性二. 默认值三. 列描述四. zerofill结束语 为什么要有约束 数据库是用来存放数据的&#xff0c;所以其需要保证数据的完整性和可靠性 数据类型也算是一种约束&#xff0c;比如&#xff0c;整型的数据无法插入字符型。 通过约束&#xff0c;让…

超详细!手把手带你实现一个完整的Promise

Promise是JavaScript中异步编程的解决方案&#xff0c;一开始在社区中提出和实现&#xff0c;后来ECMAScript将其写进了标准中。Promise有效的解决了异步编程的回调地狱问题&#xff0c;非常受开发者的欢迎。 本文首先介绍了JavaScript中异步编程的几种方式&#xff0c;再对Pr…

Vue学习之页面上中下三层布局

Vue学习之页面上中下三层布局 页面布局&#xff1a;头部&#xff0c;内容区&#xff0c;尾部&#xff0c;其中头部和尾部几乎所有页面都有&#xff0c;可抽成公共组件&#xff0c;内容区是可变的&#xff0c;由路由组件展示 页面效果 实现 &#xff08;1&#xff09;app.vue &…

为什么在使用PageHelper插件时,指定的每页记录数大小失效?显示所有的记录数

1.问题现象&#xff1a; 这里指定每页显示5条&#xff0c;却把所有的记录数都显示出来了 2.分析&#xff1a; 之前是可以的&#xff0c;然后发现&#xff1a;PageHelper.startPage(pageNum,pageSize) 和执行sql的语句 顺序颠倒了&#xff0c;然后就出错了。 3.验证&#xf…

十天学完基础数据结构-第四天(链表(Linked List))

链表的基本概念 链表是一种线性数据结构&#xff0c;与数组不同&#xff0c;链表的元素&#xff08;节点&#xff09;之间通过指针相互连接。链表有以下基本概念&#xff1a; 节点&#xff1a;链表中的每个数据项称为节点&#xff0c;每个节点包含数据和一个指向下一个节点的指…

【Unity2022】Unity实现手机游戏操控摇杆(实现操控轮盘)

文章目录 运行效果预览创建物体脚本获取RectTransform处理玩家拖动事件完整代码 获取输入运行其他文章 运行效果预览 首先展示一下本文章实现的效果&#xff1a; 创建物体 创建两个UI图像&#xff0c;一个用于表示背景&#xff0c;作为父物体&#xff0c;命名为JoyStick&am…

ubuntu安装ROS rosdep init rosdep update报错,完美解决方案!

ubuntu安装ROS rosdep init rosdep update报错&#xff0c;终于让我发现完美解决方法啦&#xff01;清华源解决 问题的原因完美解决&#xff01; 问题的原因 rosdep init&#xff0c;rosdep update报错的根本原因还是国内网络连不上外网。所以改DNS之类的方法都是比较偶然能成…

Windows安装Docker并创建Ubuntu环境及运行神经网络模型

目录 前言在Windows上安装Docker在Docker上创建Ubuntu镜像并运行容器创建Ubuntu镜像配置容器&#xff0c;使其可以在宿主机上显示GUI 创建容器并运行神经网络模型创建容器随便找一个神经网络模型试试 总结 前言 学生党一般用个人电脑玩神经网络&#xff0c;估计很少有自己的服…

nginx下载与安装教程

文章目录 nginx简介nginx的主要应用场景nginx开源项目的源码结构 使用centos7安装nginx检查centos版本号和linux内核版本检查是否安装gcc、pcre、zlib、openssl等依赖 安装nginx启动nginx停止nginx重启nginx nginx简介 nginx是一款业内流行、功能强大的web服务器。 高性能&…

会声会影2024中文版好用吗?

近些年&#xff0c;短视频逐渐走红并普及到各个领域&#xff0c;吸引着大量的自媒体从业者和爱好者投身于视频制作的热潮之中。视频剪辑软件作为视频制作不可或缺的工具&#xff0c;那么如何选择视频剪辑软件呢&#xff1f;视频剪辑软件哪个好&#xff1f; 一、视频剪辑软件有哪…

2023年,在CSDN拥有10000粉丝有多难?

该数据来源于粉丝数人数排行前5000名用户的关注用户列表中产生的&#xff0c;由于采集样本数有限&#xff0c;数据可能具有一定的误差&#xff0c;仅供参考&#xff0c;本次采样用户数大概在100万以上。 筛选条件人数粉丝人数大于50007519粉丝人数大于100003763粉丝人数大于500…

GJB 128B-2021标准版本变更汇总 ,发布, 下载

GJB 128B-2021标准版&#xff0c;下载 一、 概述 GJB 128B-2021半导体分立器件试验方法已于2022年3月1日实施&#xff0c;相对现行标准&#xff0c;新版标准对部分内容进行了变更。针对我司VDMOS产品涉及的各种方法&#xff0c;我司对新标准与旧标准的差异进行了分析。 二、 …

【AI视野·今日NLP 自然语言处理论文速览 第四十七期】Wed, 4 Oct 2023

AI视野今日CS.NLP 自然语言处理论文速览 Wed, 4 Oct 2023 Totally 73 papers &#x1f449;上期速览✈更多精彩请移步主页 Daily Computation and Language Papers Contrastive Post-training Large Language Models on Data Curriculum Authors Canwen Xu, Corby Rosset, Luc…

国庆中秋宅家自省: Python在Excel中绘图尝鲜

【一】国庆中秋: 悟 【国庆中秋】双节来临,相信各位有自己度过的方式,而我却以独特的方式度过了一个说出来不怕各位见笑的双节; 双节到来,没有太多惊喜&#xff0c;也没有太多的负面情绪, 只是喜欢独处,静静反省这些年走过的酸甜苦辣&#xff1b;生活中的许多不欢而散,不期而遇…

反素数

198. 反素数 - AcWing题库 最大的反素数也就是约数个数最多的数中最小的那个数&#xff0c;可以考虑分解质因子形式 2、3、5、7、11、13、17、19、23、29这些&#xff0c;还有每个质因子的指数一定大于等于下一个质因子的指数&#xff0c;这样可以保证约数最多的时候数字尽可能…

基于SpringBoot的智能推荐的卫生健康系统

目录 前言 一、技术栈 二、系统功能介绍 用户管理 科室类型管理 医生信息管理 健康论坛管理 我的发布 我的收藏 在线咨询 三、核心代码 1、登录模块 2、文件上传模块 3、代码封装 前言 随着信息技术在管理上越来越深入而广泛的应用&#xff0c;管理信息系统的实施在…