【LeetCode刷题笔记(8-2)】【Python】【接雨水】【单调栈】【困难】

文章目录

  • 引言
  • 接雨水
    • 题目描述
    • 提示
  • 解决方案2:【单调栈】
  • 结束语

【接雨水】

【LeetCode刷题笔记(8-1)】【Python】【接雨水】【动态规划】【困难】

引言

编写通过所有测试案例的代码并不简单,通常需要深思熟虑理性分析。虽然这些代码能够通过所有的测试案例,但如果不了解代码背后的思考过程,那么这些代码可能并不容易被理解和接受。我编写刷题笔记的初衷,是希望能够与读者们分享一个完整的代码是如何在逐步的理性思考下形成的。我非常欢迎读者的批评和指正,因为我知道我的观点可能并不完全正确,您的反馈将帮助我不断进步。如果我的笔记能给您带来哪怕是一点点的启示,我也会感到非常荣幸。同时,我也希望我的分享能够激发您的灵感和思考,让我们一起在编程的道路上不断前行~

接雨水

题目描述

给定 n 个非负整数表示每个宽度为 1 的柱子的高度图,计算按此排列的柱子,下雨之后能接多少雨水。

在这里插入图片描述
图片来源

提示

  • n == height.length
  • 1 <= n <= 2 * 104
  • 0 <= height[i] <= 105

解决方案2:【单调栈】

图1
通过观察图像,我们可以发现红色方框部分与木桶的形态颇为相似。让我们富有想象力地将最左侧高度为2的柱子视作木桶的左侧板,而将最右侧高度为3的柱子视作木桶的右侧板。基于深入人心的【木桶原理】,一个木桶的装水量总是受限于其最短的那块木板 ==> 若能在上图中探寻到所有“有效的”木桶,并计算这些木桶的装水量再进行汇总,我们便能获得所求的结果。

问题1:如何获取所有“有效的”木桶呢?

首先,对木桶的组成部分有个清晰的定义:木桶分为【左侧板】【底板】和【右侧板】三个部分。
在这里插入图片描述
通过观察图像,我们可以发现,从左到右遍历height数组时,柱子高度会呈现出一种特殊的规律。首先,从左侧板到底板的过程中,柱子高度会逐渐降低,形成一个递减的趋势。接着,从底板到右侧板的过程中,柱子高度则会逐渐升高,形成一个递增的趋势。更为有趣的是,图像中多次出现了这种“递减-递增”的模式转换,每一次的转换都可能构成一个“有效的”木桶。这种观察不仅揭示了数据背后的隐藏规律,也为我们解决问题提供了新的视角和思路。

问题2:如何捕捉到这种“递减-递增”的模式转换呢?

使用单调栈

要捕捉这种递减-递增的模式转换,我们可以使用单调栈。单调栈是一种数据结构,它能够保持栈内元素按照特定的顺序排列。在这个问题中,我们可以使用一个单调递减栈stack来存储数组 height下标。 ==> 用单调栈存储潜在的【左侧板】和【底板】

细节1: 之所以选择存储元素的“下标”,是为了方便计算“有效”木桶的宽度。通过存储下标,我们可以轻松地获取到木桶的左侧板、底板和右侧板的位置,从而计算出木桶的宽度。

从左往右遍历height数组,如果新的元素height[i]比栈顶元素height[stack[-1]]还大 ⇒ 不满足递减 ⇒ 出现了右侧板,那么此时的栈顶下标top=stack.pop()表示的就是“桶底”,而栈顶元素height[top]表示底板距离地面(柱子高度为0视为地面)的高度;倘若stack中存储不止一个下标,那么弹出栈顶下标top后,stack一定非空 ⇒ 新的栈顶下标left=stack[-1]表示的就是“左侧板”所在位置,而新的栈顶元素height[left]表示左侧板的高度**。当“底板”和“左侧板”都存在时,说明存在“有效木桶”,那么新的元素下标i可以用变量right进行表征,即right=i,表示右侧板所在位置。那么Width = right - left - 1即为木桶的有效宽度

在这里插入图片描述

细节2: 之所以说栈顶元素height[top]表示底板距离地面的高度是因为每个底板不一定都在地面上。因此,根据木桶原理,木桶的有效高度Height = min(height[left],height[right]) - height[top] ⇒ 该木桶容纳水的含量 water = Height * Width

细节3: 在某些区域,可能会有多个木桶。就像上图所示,红色框代表的大木桶下面,还隐藏着一个绿色框代表的小木桶。根据我们的生活常识,当给这两个叠在一起的木桶装水时,首先装满的一定是小木桶。当小木桶装满水后,我们可以将小木桶当作大木桶的底板(小木桶的左侧板当作大木桶的底板,可和代码结合理解),继续给大木桶装水。而基于【单调栈】的解法,正好与我们的常识保持一致。

完整代码

class Solution:def trap(self, height: List[int]) -> int:total_water = 0 # 记录水的容量stack = list() # 创建单调递减栈n = len(height)for i, h in enumerate(height): # 遍历数组height的每个元素# 当栈非空 且 新的元素h比栈顶元素height[stack[-1]]还大时 while stack and h > height[stack[-1]]: right = i # 找到右侧板,用变量right进行表征top = stack.pop() # 栈顶下标表示底板,不可能在表示左侧板,更不可能是右侧板 ---> 直接弹出if not stack: # 栈空 --> 没有找到左木板,不能组成有效的木桶break # 跳出while循环 寻找下一个右木板else: # 找到左木板left = stack[-1] # 当前栈顶表示左木板的下标可能会作为下一个有效木桶的底板 --> 不能弹出 if height[left] == height[top]:# 左木板高度和底板高度一致 ---> 根据木板原理,装不下任何水continue # 固定右侧板,寻找下一个有效木桶else: # height[top] < height[left]  且  height[top] < height[right] 恒成立# 这个木桶一定能装到水bucket_width = right - left - 1bucket_height = min(height[left], height[right]) - height[top]total_water += bucket_width * bucket_height# 当前扮演右木板 --> 接着可能会扮演左木板/桶底stack.append(i)return total_water

运行结果
在这里插入图片描述

复杂度分析

  • 时间复杂度:O(N),其中 N 是数组height元素的数量。
    • 外层for循环遍历数组 height ===> O(N)
    • 内层while循环中, height每个元素最多出/入栈一次 ===> O(1)
  • 空间复杂度:O(N)
    • 栈空间元素个数不会超过N ===> O(N)

结束语

  • 亲爱的读者,感谢您花时间阅读我们的博客。我们非常重视您的反馈和意见,因此在这里鼓励您对我们的博客进行评论。
  • 您的建议和看法对我们来说非常重要,这有助于我们更好地了解您的需求,并提供更高质量的内容和服务。
  • 无论您是喜欢我们的博客还是对其有任何疑问或建议,我们都非常期待您的留言。让我们一起互动,共同进步!谢谢您的支持和参与!
  • 我会坚持不懈地创作,并持续优化博文质量,为您提供更好的阅读体验。
  • 谢谢您的阅读!

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

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

相关文章

200kw直流电子负载测试

在进行200kw直流电子负载测试时&#xff0c;需要设置合适的负载参数&#xff0c;如电流、电压和功率等&#xff0c;并记录测试结果。在测试过程中&#xff0c;可以通过改变负载参数来模拟不同工作条件下的电子设备的性能。通过对电子设备在不同负载条件下的响应进行测试和分析&…

JupyterHub 如何切换 conda 小环境

JupyterHub 如何切换 conda 小环境 服务器已经部署好 JupyterHub &#xff0c;相关端口请看对应答疑群群公告。在Jupyterhub 中使用 conda 创建的小环境&#xff0c;首先 ssh 登录上服务器或者在 JupyterHub 网页端打开终端 terminal。然后安装 conda &#xff0c;方法请见 Q4&…

【MyBatis Plus】逻辑删除、分页、乐观锁的应用及讲解

&#x1f389;&#x1f389;欢迎来到我的CSDN主页&#xff01;&#x1f389;&#x1f389; &#x1f3c5;我是Java方文山&#xff0c;一个在CSDN分享笔记的博主。&#x1f4da;&#x1f4da; &#x1f31f;推荐给大家我的专栏《MyBatis-Plus》。&#x1f3af;&#x1f3af; &am…

改进灰狼算法求解:考虑需求响应的风-光柴-储容量优化配置

目录 文章摘要&#xff1a; 亮点&#xff1a; 研究背景&#xff1a; 考虑需求相应的容量配置&#xff1a; 风、光、柴、储微电网模型&#xff1a; 储能配置模型&#xff1a; 改进的灰狼算法&#xff1a; 基于余弦规律变化的收敛因子 引入动态权重策略 运行效果&#…

数据结构:图文详解 队列 | 循环队列 的各种操作(出队,入队,获取队列元素,判断队列状态)

目录 队列的概念 队列的数据结构 队列的实现 入队 出队 获取队头元素 获取队列长度 循环队列的概念 循环队列的数据结构 循环队列的实现 判断队列是否为空 判断队列是否已满 入队 出队 得到队头元素 得到队尾元素 队列的概念 队列&#xff08;Queue&#xff0…

基于单片机的视力保护及身姿矫正器设计(论文+源码)

1. 系统设计 在本次设计中&#xff0c;其系统整个框图如图2-1所示。其主要的核心控制模块由超声波模块&#xff0c;光敏电阻&#xff0c;按键模块&#xff0c;复位电路&#xff0c;红外模块&#xff0c;LCD显示等组成。其包括自动模式&#xff0c;手动模式。自动模式&#xff…

upload-labs笔记

简介 upload-labs是一个使用php语言编写的&#xff0c;专门收集渗透测试和CTF中遇到的各种上传漏洞的靶场。旨在帮助大家对上传漏洞有一个全面的了解。目前一共21关&#xff0c;每一关都包含着不同上传方式。 文件上传漏洞是指&#xff1a; Web 服务器允许用户将文件上传至其…

Linux部署Nacos注册中心结合内网穿透实现远程访问UI管理界面

文章目录 1. Docker 运行Nacos2. 本地访问Nacos3. Linux安装Cpolar4. 配置Nacos UI界面公网地址5. 远程访问 Nacos UI界面6. 固定Nacos UI界面公网地址7. 固定地址访问Plik8. 结语 Nacos是阿里开放的一款中间件,也是一款服务注册中心&#xff0c;它主要提供三种功能&#xff1a…

多序列图像拼接

这里写自定义目录标题 图像匹配图像匹配代码 图像融合main.py运行代码 总的来说&#xff0c;步骤如下&#xff1a; 效果如下&#xff1a; 拼接好的图如下&#xff1a; 图像匹配 依次为 特征点提取&#xff0c;特征点筛选&#xff0c;图像变换。 常见的图像匹配算法有&…

2024上半年软考别轻易尝试!先了未发布

最近几年&#xff0c;软件考试变得非常受欢迎&#xff01;不论你的专业、学历或工作时间如何&#xff0c;你都可以报名参加&#xff0c;而且通过考试取得证书还能用来抵扣个人所得税、评职称、帮助落户和参与招投标等等。 身边的朋友们纷纷参加软考&#xff0c;这让我也产生了…

下一代实时数据库:Apache Doris 【六】数据划分

3.4 数据划分 3.4.1 列定义3.4.2 分区与分桶3.4.3 PROPERTIES3.4.4 ENGINE3.4.5 其他后记 3.4 数据划分 以 3.3.2 的建表示例来理解。 3.4.1 列定义 以 AGGREGATE KEY 数据模型为例进行说明。更多数据模型参阅 Doris 数据模型。 列的基本类型&#xff0c; 可以通过在 mysql-cli…

山区老人爱的礼物丨走进武隆区土地乡为山区老人送温暖

从车水马龙的城市到人烟稀少的乡村&#xff0c;穿越重峦叠嶂的高山&#xff0c;见到的是独属于大山的辽阔和山区老人眼中的星河。近日&#xff0c;传益千里为爱出发&#xff0c;在三棵柚公益基金会的支持下开展“山区老人爱的礼物”公益计划&#xff0c;走进武隆区土地乡&#…

Unity Meta Quest 一体机开发(十一):【手势追踪】远距离抓取

文章目录 &#x1f4d5;教程说明&#x1f4d5;玩家配置 DistanceHandGrabInteractor&#x1f4d5;物体配置 DistanceHandGrabInteractable&#x1f4d5;调整物体飞向手部的速度&#x1f4d5;调整探测物体的范围⭐HandFrustumNarraw⭐HandFrustumWide⭐HeadFrustum 此教程相关的…

探讨前端技术的未来:创新与适应的必要性

一、引言 2023年&#xff0c;IT圈似乎被一种悲观的论调所笼罩&#xff0c;那就是“Java 已死、前端已凉”。然而&#xff0c;真相是否如此呢&#xff1f;本文将围绕这一主题&#xff0c;探讨前端的现状和未来发展趋势。 二、为什么会出现“前端已死”的言论 这一言论的出现并…

盛元广通农产品质量检测实验室管理系统

盛元广通农产品质量检测实验室管理系统旨在打造智慧化市、区/镇、企业三位一体的区域安全监管体系&#xff0c;系统可以记录和追踪样品的来源、处理过程和结果&#xff0c;确保样品的安全性和可追溯性自动化检测流程&#xff0c;包括检测方法的设定、数据的记录和分析等&#x…

健康卤味思想引领市场新潮流,卤味市场迎来健康变革

健康卤味思想正在逐渐渗透到卤味市场中&#xff0c;引领着消费者对于卤味产品的选择和需求。这一变革不仅为消费者带来了更加健康、美味的卤味产品&#xff0c;也为卤味市场注入了新的活力。 一、健康卤味思想的兴起 随着消费者对于健康饮食的关注度不断提高&#xff0c;健康卤…

【node】 地址标准化 解析手机号、姓名、行政区

地址标准化 解析手机号、姓名、行政区 实现效果链接源码 实现效果 将东光县科技园南路444号马晓姐13243214321 解析为 东光县科技园南路444号 13243214321 河北省;沧州市;东光县;东光镇 马晓姐 console.log(address, phone, divisions,name);链接 API概览 源码 https://gi…

Java 基础学习(九)API概述、Object、String、正则表达式

1 API概述 1.1 API概述 1.1.1 什么是API API(Application Programming Interface)&#xff0c;意为&#xff1a;应用程序接口。API就是已经写好的的程序或功能&#xff0c;程序要需要时可以直接调用&#xff0c;无需再次编写。 API可以大致分为如下几类&#xff1a; 编程语…

美创“四大能力”为工业企业数据安全构筑韧性防线

12月14日&#xff0c;“数据与网络安全创新 赋能工业企业数字化转型”主题沙龙在杭州举行。本次活动由浙江省工业软件产业技术联盟、浙江省网络空间安全创新研究中心、浙江省图灵互联网研究院主办&#xff0c;浙江省网络空间安全协会数据安全治理专委会、杭州市计算机学会、长三…

华硕天选大小核设置

电脑:华硕天选4, CPU:13th Gen Intel(R) Core(TM) i9-13900H 2.60 GHz在奥创智控中心(Armoury Crate)调整大小核,应用重启即可