数据结构:单调栈

1.单调栈

     单调栈是一种数据结构,其中存放的数据应该是有序的,所以单调栈也有单调递减栈单调递增栈

单调递增栈:栈顶到栈底的元素大小是从小到大
单调递减栈:栈顶到栈底的元素大小是从大到小

     单调栈主要就是用来求一个给定序列中每个数左边离它最近的比它大或小的数。如果找的是比它小的数,就是构造一个单调递减栈;如果找的是比它大的数,那构造的就是一个单调递增栈。

2.单调栈模拟

      假如我们现在有一个序列10,2,8,5,13,我们要找每个数离它最近的比它大的数,我们要构造一个单调递增的栈,则如果栈为空或者入栈的元素大小小于栈顶值,就入栈,否则入栈会破坏栈的单调性,这时候比入栈元素小的元素全部出栈。

      10入栈时,栈为空,直接入栈,栈有一个元素10;

      2入栈时,栈顶元素10比2大,则入栈,栈内元素为10和2;

      8入栈时,栈顶元素2比8小,则栈顶元素出栈,此时栈顶元素为10,比8大,8可以入栈,栈内元素为10和8;

     5入栈时,栈顶8比5大,可以入栈,栈内元素为10,8,5;

     13入栈时,栈顶元素5比13小,出栈;8比13小,出栈;10比13小,出栈,最后栈为空,13入栈,栈内只有12。

      单调递减栈的原理和递增类似

代码:

C:
//构造单调递增栈
int top=0;
for(int i=0;i<n;i++)
{
   if(top==0||stk[top]>=i}
   {
     stk[++top]=i;//当前元素入栈
   }
   else
   {
      while(top&&stk[top]<i)
      {
        top--;//出栈
      }
      stk[++top]=i;//当前元素入栈
   }
}

//构造单调递减栈
int top=0;
for(int i=0;i<n;i++)
{
   if(top==0||stk[top]<=i}
   {
     stk[++top]=i;//当前元素入栈
   }
   else
   {
      while(top&&stk[top]>i)
      {
        top--;//出栈
      }
      stk[++top]=i;//当前元素入栈
   }
}
 C++:
//构造单调递增栈
stack<int>stk;
for(int i=0;i<n;i++)
{
  while(!stk.empty()&&stk.top()<i)
  {
    stk.pop()
  }
   stk.push(i);
}

//构造单调递减栈
stack<int>stk;
for(int i=0;i<n;i++)
{
  while(!stk.empty()&&stk.top()>i)
  {
    stk.pop()
  }
   stk.push(i);
}

 3.单调栈应用(C++)

     其实我们可以看到这也是类似最近匹配的问题,栈最擅长这种问题了

3.1 每日温度

vector<int> dailyTemperatures(vector<int>& temperatures) {
        vector<int> res(temperatures.size(), 0);
        stack<int> stk;
        for (int i = 0; i < temperatures.size(); ++i) {
            while (!stk.empty() && temperatures[stk.top()] < temperatures[i]) {
                res[stk.top()] = i - stk.top();
                stk.pop();
            }
            stk.push(i);
        }
        return res;
    }

      给定一个温度序列,让你求每个温度离它最近的比它高的温度是之后第几天,显然符合单调递增栈的特征,我们定义一个栈stk来存储每个温度对应的下标和存储结果的vector数组res,从头开始遍历,如果栈为空或者栈顶下标对应的温度大于当前温度值,则当前温度对应的下标入栈;如果不为空且栈顶下标对应的温度小于当前温度值,说明我们找到了这个温度离它最近的比它高的温度值,那我们就把两个温度对应天数的差值放入res数组中,即res[stk.top()]=i-stk.top(),然后再让栈顶元素出栈,把这个温度对应的下标入栈即可,最后返回结果数组res。

3.2 接雨水

int trap(vector<int>& height) {
      int ans=0;
      stack<int>st;
      for(int i=0;i<height.size();i++)
      {
          while(!st.empty()&&height[st.top()]<height[i])
          {
              int cur=st.top();
              st.pop();
              if(st.empty())break;
              int l=st.top();
              int r=i;
              int h=min(height[l],height[r])-height[cur];
              ans+=(r-l-1)*h;
          }
          st.push(i);
      }
      return ans;
    }

       这是一个单调递减栈,当我们找到一根比前面高的柱子时,就可以计算接到的雨水了。更低的柱子我们就入栈,当出现高于栈顶的柱子时,我们就可以计算已经接到的雨水,然后出栈把当前当前的柱子入栈。

        需要注意的是,雨水的右边r是当前的索引i,底部是栈顶st.top(),因为遇到了更高的柱子,所以雨水的左边即将出栈,使用cur来记录它,l就是新的栈顶,这样雨水的区域就确定了,高度就是左右两边更低的一边减去底部,宽度就是左右中间。

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

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

相关文章

上海周边公路骑行路线分享,维乐带你抓住秋天的小尾巴

路线一&#xff1a;松江郊里骑行      在魔都上海&#xff0c;藏着一条自然风景适宜&#xff0c;能眺望黄浦江的美丽骑行路线。导航到华长路杨家角就能到达起点&#xff0c;一路向西&#xff0c;这里路况非常好&#xff0c;只有一条小道&#xff0c;没有汽车的障碍&#xf…

数组(定义,静态初始化,地址值,元素访问,索引,遍历,动态初始化,两种初始化的区别,练习)

文章目录 1.数组概念&#xff1a; 2.数组的定义格式一&#xff1a;格式二&#xff1a;详解&#xff1a;注意点&#xff1a; 3.数组的静态初始化完整格式&#xff1a;格式详解&#xff1a;注意点&#xff1a;简化格式:练习1&#xff1a;练习2&#xff1a;练习3&#xff1a; 4.地…

使用opencv+tesseract识别图片中的表格

描述 在java环境中使用opencv和tesserac识别一个图片表格 环境&#xff1a;opencv和tesseract安装在linux环境下&#xff0c;docker将运行springboot服务 opencv和tesseract的安装和docker加载可参考之前的文章 过程 将图片进行预处理&#xff0c;过滤掉颜色等干扰元素 提…

基于Ubuntu环境Git服务器搭建及使用

基于Ubuntu环境Git服务器搭建及使用 Chapter1 搭建本地git服务器及详细操作步骤1.搭建本地git服务器1.1 环境1.2 服务端配置1.3 创建git专属用户1.4 创建git仓库1.5 配置免密登录基础 2.客户端拉取推送代码2.1客户端创建ssh公钥 2.2 免密配置3.仓库使用&#xff08;拉取及推送代…

记chrome的hackbar无法post php://input的问题

尽管hackbar支持post请求体&#xff0c;但是当请求体里面没有等于号的时候&#xff0c;无法post出去&#xff0c;这样如果需要使用php://input绕过waf的时候就没法做。 在开发人员工具的网络里面可以看到不使用等于号的情况下没有荷载。 之后在这里看到了解决方法&#xff0c;…

【javaSE】代理并不难

代理&#xff1a; 代理模式最主要的就是在不改变原来代码&#xff08;就是目标对象&#xff09;的情况下实现功能的增强 在学习AOP之前先了解代理&#xff0c;代理有两种&#xff1a;一种是动态代理&#xff0c;一类是静态代理。 静态代理 相当于是自己写了一个代理类&#…

pandas将dataframe列中的list转换为多列

在应用机器学习的过程中&#xff0c;很大一部分工作都是在做数据的处理&#xff0c;一个非常常见的场景就是将一个list序列的特征数据拆成多个单独的特征数据。 比如数据集如下所示&#xff1a; data [[John, 25, Male,[99,100,98]],[Emily, 22, Female,[97,99,98]],[Michae…

JUC Lock 锁入门

文章目录 死锁&#xff08;Deadlock&#xff09;通过 Visualvm 等工具排查死锁 活锁park & unpark与 wait & notify 的区别park & unpark 实现&#xff1a;点外卖 Lock 对象ReentrantLock 可重入锁可重入lockInterruptibly 方法上锁&#xff08;可打断&#xff09;…

门诊病历系统教程,社区诊所电子处方系统软件操作教程

一、软件程序问答 门诊病历系统教程&#xff0c;社区诊所电子处方系统软件操作教程 1、电子处方软件在开处方时候&#xff0c;可以一键导入模板吗&#xff1f; 如下图&#xff0c;软件以 佳易王诊所电子处方软件V17.1为例说明 软件右侧点击 配方模板&#xff0c;只需输入症…

以太坊代币标准解读及相关Dapp的搭建

文章目录 什么是以太坊代币标准1、什么是以太坊2、以太坊代币标准 同质化代币 Dapp 搭建1、MetaMask 的安装2、Ganache 的安装3、实现 ERC-20 代币协议4、前端页面的编写5、部署流程及操作演示 什么是以太坊代币标准 1、什么是以太坊 以太坊&#xff08;Ethereum&#xff09;是…

2024年,程序员有哪些危机,有什么应对方式?

在2024年&#xff0c;程序员可能面临的危机主要包括技术更新迅速、职业竞争激烈、工作与生活平衡困难等方面。 为了应对这些危机&#xff0c;程序员可以采取以下策略&#xff1a; 技术更新迅速&#xff1a;随着技术的不断发展&#xff0c;新的编程语言和工具不断涌现&#xff…

52.网游逆向分析与插件开发-游戏反调试功能的实现-检测调试器

码云地址&#xff08;master分支&#xff09;&#xff1a;https://gitee.com/dye_your_fingers/sro_-ex.git 码云版本号&#xff1a;be9f058bfaaa4b015f2659db842e07ee37e58996 代码下载地址&#xff0c;在 SRO_EX 目录下&#xff0c;文件名为&#xff1a;SRO_Ex检测调试器.z…

迈向通用异常检测和理解:大规模视觉语言模型(GPT-4V)率先推出

PAPERCODEhttps://arxiv.org/pdf/2311.02782.pdfhttps://github.com/caoyunkang/GPT4V-for-Generic-Anomaly-Detection 图1 GPT-4V在多模态多任务异常检测中的综合评估 在这项研究中&#xff0c;我们在多模态异常检测的背景下对GPT-4V进行了全面评估。我们考虑了四种模式&#…

c 生成16×16像素点的rgb格式图片

想验证jpeg 编解码各个环节是否正确&#xff0c;特小尺寸的yuv格式图片找不到。特意用c代码生成一个1616像素点的rgb格式图片,再转换为yuv444格式&#xff0c;再88分割&#xff0c;余弦转换&#xff0c;量化&#xff0c;Z变换&#xff0c;霍夫曼编码&#xff0c;生成比特流&…

你真的懂Hello World!吗?(编译与链接,静态链接与动态链接)

&#x1f4ab;Hello World! 对于大家来说Hello World!应该是最熟悉不过的一句话&#xff0c;我们从Hello World!走进了计算机的世界&#xff0c;但是你真的了解Hello World!吗&#xff1f;你又思考过它背后蕴含的机理吗&#xff1f;他是怎么从代码变成程序的你真的思考过吗&…

react18框架笔记

React React 是 facebook 出的一款针对视图层的库(library)。它是基于单向数据流思想开发的&#xff0c;主要的一个功能就是针对视图显示&#xff0c;让我们把一个项目拆分成一个一个组件进行开发维护。 官网 目前我们讲的 react 是基于 18.2 的版本。react 每一个版本更新之…

谷歌Linux内核自动测试平台架构介绍-用自动测试测试难以测试的问题

1 摘要 内核和硬件等低级系统已被证明极难进行有效测试&#xff0c;因此&#xff0c;许多内核测试都是以手动为主方式进行的。现有的大多数测试框架都是为测试与底层平台隔离的高级软件而设计的&#xff0c;而底层平台被假定是稳定可靠的。测试底层平台本身需要一套全新的假设…

命令行万年历程序

在linux终端里看不了日历&#xff0c;我不答应&#xff01;代码仓库地址 一、命令行运行的效果图 如果输入的年份是目前所在年&#xff0c;会标注当天的日期 二、代码实现 1. 判断闰年 bool judge_leap_year(int year) {return ((year % 4 0) && (year % 100 ! 0)) …

听GPT 讲Rust源代码--src/tools(37)

File: rust/src/tools/clippy/clippy_lints/src/explicit_write.rs 在Rust源代码中&#xff0c;explicit_write.rs这个文件是Clippy的一个lint插件&#xff0c;其作用是检查代码中的write!、writeln!宏使用时的不当或繁琐的情况&#xff0c;并给出相关的警告或建议。 具体来说&…

浅谈冯诺依曼体系和操作系统

&#x1f30e;冯诺依曼体系结构 文章目录 冯诺依曼体系结构 认识冯诺依曼体系结构       硬件分类       各个硬件的简单认识         输入输出设备         中央处理器         存储器 关于内存 对冯诺依曼体系的理解 操作系统 操作系统…