每日一题——接雨水(单调栈)

news2024/9/24 23:31:31

接雨水——单调栈

题目链接


单调递增的栈还是单调递减的栈

我们常说的**”积水成洼“**,指的就是说:当两边地势高于中间的地势时,中间的区域就成了洼地,也就可以积水了。

这一题就是如此,我们需要通过一个栈来记录数据,只要记录的数据有高——低——高这一过程,就说明形成了洼地,也就可以计算雨水容量了。

所以我们应该用一个非递增的栈来存放数据,我们保证栈中的数据是非递增的,这样当一个数据准备进栈时,如果进栈元素小于栈顶元素,那就仍旧满足非递增顺序,直接入栈即可,而如果进展元素大于栈顶元素,就说明栈顶元素的前一个元素,栈顶元素,进栈元素这三个元素达成了高——低——高这一条件,也就可以进行容量的计算了

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-l92srQHv-1692435320269)(C:/Users/HUASHUO/AppData/Roaming/Typora/typora-user-images/image-20230819154920085.png)]


实现思路

我们已经知道要用非递增的单调栈来解决这个问题,那么接下来就要讨论如何做具体的实现了。

这里我们利用栈来储存数组元素的下标

规定栈顶元素为stack_top,栈顶元素的前一个为left(注意:二者都是构成容器的数组元素的下标

我们用i来遍历构成容器的数组,需要分以下几种情况讨论:

  • 当栈为空或者进栈元素小于栈顶元素时,进栈元素height[i]直接入栈即可。如图:

  • 否则,当栈不为空并且进栈元素大于栈顶元素时,为保证栈的非递增特性,要通过循环不断移除栈元素,同时:

    • 如果出栈顶元素后栈为空,那么直接将进栈元素height[i]入栈即可。如图:

    • 如果出栈顶元素后栈不为空,那么栈顶元素的前一个元素height[left]、栈顶元素height[stack_top]、进栈元素height[i]就达成了高——低——高的条件,即形成了积水区域。积水区域的宽wide就是i - left - 1,高度high就是min(height[i], height[left] - height[stack_top]),最后容积也就是wide * high。如图:

      [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-c7OeWwOf-1692435320269)(C:/Users/HUASHUO/AppData/Roaming/Typora/typora-user-images/image-20230819162535236.png)]

接下来,我们以题目中的例子height = [0,1,0,2,1,0,1,3,2,1,2,1]为例,模拟整个过程。

实现代码

int trap(int* height, int heightSize){
    //申请栈空间
    int *stack = (int*)malloc(sizeof(int) * heightSize);
    int top = 0;

    int volum = 0;  //容量

    for (int i=0; i<heightSize; i++)
    {
        //如果栈不为空并且遍历元素大于栈顶元素
        //由于要保证栈的单调性,所以无论如何栈顶元素都要出栈
        while (top != 0 && height[i] > height[stack[top - 1]])
        {
            int stack_top = stack[--top];

            //如果栈顶元素出栈后仍不为空,就说明可以容纳雨水
            if (top != 0)
            {

                //计算容量
                int left = stack[top - 1];
                int wide = i - left - 1;
                int high = fmin(height[left], height[i]);

                volum += wide * (high - height[stack_top]);
            }

            //如果计算完这一次后仍满足循环条件,就说明还可能继续装水
        }
        //无论是否进入循环,遍历元素都要入栈
        stack[top++] = i;
    }

    //释放栈空间
    free(stack);
    return volum;
}

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

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

相关文章

UE4中关于利用粒子系统做轨迹描绘导致系统流畅性下降的问题

UE4中关于利用粒子系统做轨迹描绘导致系统流畅性下降的问题 文章目录 UE4中关于利用粒子系统做轨迹描绘导致系统流畅性下降的问题前言假设及验证1. 过多的粒子发射器影响仿真系统2. 粒子数目太多&#xff0c;降低粒子发射频率&#xff0c;同时增大粒子显示范围3. 把信息输出到屏…

揭秘程序员的鄙视链,你在哪一层?看完我想哭

虽然不同的编程语言都有其优缺点&#xff0c;而且程序员之间的技能和能力更加重要&#xff0c;但是有些程序员可能会因为使用不同的编程语言而产生鄙视链。 以下是一些可能存在的不同编程语言程序员之间的鄙视链&#xff1a; 低级语言程序员鄙视高级语言程序员&#xff1a;使用…

Java教程:如何使用切面环绕方法对所有接口进行添加出入参日志保存功能

背景&#xff1a; ----在很多时候我们做开发时&#xff0c;往往只是提供一个对外接口来进行前后端调试&#xff0c;或第三方系统联调&#xff0c;并使用log进行日志打印&#xff0c;每当出现问题进行排查时&#xff0c;只需要查看服务器日志就可以定位到问题&#xff0c;从而解…

Three.js程序化3D城市建模【OpenStreetMap】

对于我在 Howest 的研究项目&#xff0c;我决定构建一个 3D 版本的 Lucas Bebber 的“交互式讲故事的动画地图路径”项目。 我将使用 OSM 中的矢量轮廓来挤出建筑物的形状并将它们添加到 3js 场景中&#xff0c;随后我将对其进行动画处理 推荐&#xff1a;用 NSDT编辑器 快速搭…

在抽象类中使用@Autowired注入其他bean

概述 今天写代码时&#xff0c;使用模板设计模式&#xff0c;需要在抽象类中使用Autowired注入指定的Bean&#xff0c;然后调用指定方法。 问题 发现Autowired注解有红色下划线 解决 其实没有什么关系&#xff0c;只要实现类继承这个抽象方法&#xff0c;然后加入IOC容器&am…

深入理解SSO原理,项目实践使用一个优秀开源单点登录项目(附源码)

深入理解SSO原理,项目实践使用一个优秀开源单点登录项目(附源码)。 一、简介 单点登录(Single Sign On),简称为 SSO。 它的解释是在多个应用系统中,用户只需要登录一次就可以访问所有相互信任的应用系统。 ❝ 所谓一次登录,处处登录。同样一处退出,处处退出。 ❞ 二…

内核配置知识

Linux内核配置系统的组成 Linux内核源码很多&#xff0c;有上千条配置选项&#xff0c;配置相当复杂。 为了更好选择自己想要的功能配置&#xff0c;linux内核源码组织了一个配置系统&#xff1b; 配置系统包括三部分&#xff1a; Makefile&#xff1a;负责整体的配置编译 …

人工智能在网络安全中的作用:当前的局限性和未来的可能性

人工智能 (AI) 激发了网络安全行业的想象力&#xff0c;有可能彻底改变安全和 IT 团队处理网络危机、漏洞和勒索软件攻击的方式。 然而&#xff0c;对人工智能的能力和局限性的现实理解至关重要&#xff0c;并且存在许多挑战阻碍人工智能对网络安全产生直接的变革性影响。 在…

Python学习 -- 高阶、闭包、回调、偏函数与装饰器探究

Python函数作为编程的核心&#xff0c;涵盖了众多令人兴奋的概念&#xff0c;如高阶函数、闭包、回调、偏函数和装饰器。本篇博客将深入研究这些概念&#xff0c;结合实际案例为你解析函数的精妙&#xff0c;以及如何巧妙地运用它们来构建更强大、灵活的程序。 高阶函数&#…

模型数据处理-数据放入 session和@ModelAttribute 实现 prepare 方法详细讲解

&#x1f600;前言 本文详细讲解了模型数据处理-数据放入 session和ModelAttribute 实现 prepare 方法详细讲解 &#x1f3e0;个人主页&#xff1a;尘觉主页 &#x1f9d1;个人简介&#xff1a;大家好&#xff0c;我是尘觉&#xff0c;希望我的文章可以帮助到大家&#xff0c…

518. 零钱兑换 II

518. 零钱兑换 II 原题链接&#xff1a;完成情况&#xff1a;解题思路&#xff1a;参考代码&#xff1a; 原题链接&#xff1a; 518. 零钱兑换 II https://leetcode.cn/problems/coin-change-ii/description/ 完成情况&#xff1a; 解题思路&#xff1a; 参考代码&#xff1…

数据在内存中的存储(deeper)

数据在内存中的存储&#xff08;deeper&#xff09; 一.数据类型的详细介绍二.整形在内存中的存储三.浮点型在内存中的存储 一.数据类型的详细介绍 类型的意义&#xff1a; 使用这个类型开辟内存空间的大小&#xff08;大小决定了使用范围&#xff09;如何看待内存空间的视角…

GBU816-ASEMI新能源专用整流桥GBU816

编辑&#xff1a;ll GBU816-ASEMI新能源专用整流桥GBU816 型号&#xff1a;GBU816 品牌&#xff1a;ASEMI 封装&#xff1a;GBU-4 恢复时间&#xff1a;&#xff1e;50ns 正向电流&#xff1a;8A 反向耐压&#xff1a;1600V 芯片个数&#xff1a;4 引脚数量&#xff1…

关于spring嵌套事务,我发现网上好多热门文章持续性地以讹传讹

事情起因是&#xff0c;摸鱼的时候在某平台刷到一篇spring事务相关的博文&#xff0c;文章最后贴了一张图。里面关于嵌套事务的表述明显是错误的。 更奇怪的是&#xff0c;这张图有点印象。在必应搜索关键词PROPAGATION_NESTED出来的第一篇文章&#xff0c;里面就有这这部份内…

使用chatgpt将中文翻译成学术英语

使用chatgpt将中文翻译成学术英语 方式一 使用chatgpt翻译 你是一个英文学术论文写作专家&#xff0c;以下是一篇学术论文中的一段内容&#xff0c;请先对其进行翻译为英文&#xff0c;并将此部分润色以满足学术标准&#xff0c;提高语法、清晰度和整体可读性&#xff0c;给…

408反向改考自命题的211学校,计算机招生近500人!今年能捡到漏吗?

贵州大学(C) 考研难度&#xff08;☆☆☆&#xff09; 内容&#xff1a;23考情概况&#xff08;拟录取和复试分析&#xff09;、院校概况、23专业目录、23复试详情、各专业考情分析。 正文1498字&#xff0c;预计阅读&#xff1a;3分钟。 2023考情概况 贵州大学计算机相关各…

基于SpringCloud的会议室预约系统Java基于微服务的会议室报修系统【源码+lw】

&#x1f495;&#x1f495;作者&#xff1a;计算机源码社 &#x1f495;&#x1f495;个人简介&#xff1a;本人七年开发经验&#xff0c;擅长Java、微信小程序、Python、Android、大数据等&#xff0c;大家有这一块的问题可以一起交流&#xff01; &#x1f495;&#x1f495…

.net通过S7.net读写西门子PLC中,字符串,bool,整数,小数及byte型

注&#xff1a;.net中通过TCP/IP方式通过S7.net.dll动态库&#xff0c;连接到西门子PLC&#xff0c;西门子程序中许勾选优化块&#xff0c;程序读取需要 db块号偏移量 一。使用VS项目&#xff0c;在项目中添加S7.net动态库 代码中引用S7.net动态库 using S7.Net; 实例化PLC服…

Linux网络编程:Socket套接字编程

文章目录&#xff1a; 一&#xff1a;定义和流程分析 1.定义 2.流程分析 3.网络字节序 二&#xff1a;相关函数 IP地址转换函数inet_pton inet_ntop&#xff08;本地字节序 网络字节序&#xff09; socket函数(创建一个套接字) bind函数(给socket绑定一个服务器地址结…

使用线性回归模型优化权重:探索数据拟合的基础

文章目录 前言一、示例代码二、示例代码解读1.线性回归模型2.MSE损失函数3.优化过程4.结果解读 总结 前言 在机器学习和数据科学中&#xff0c;线性回归是一种常见而重要的方法。本文将以一个简单的代码示例为基础&#xff0c;介绍线性回归的基本原理和应用。将使用Python和Nu…