【LeetCode刷题笔记(8-1)】【Python】【接雨水】【动态规划】【困难】
文章目录
- 引言
- 接雨水
- 题目描述
- 提示
- 解决方案1:【动态规划】
- 结束语
接雨水
引言
编写通过所有测试案例的代码并不简单,通常需要深思熟虑和理性分析。虽然这些代码能够通过所有的测试案例,但如果不了解代码背后的思考过程,那么这些代码可能并不容易被理解和接受。我编写刷题笔记的初衷,是希望能够与读者们分享一个完整的代码是如何在逐步的理性思考下形成的。我非常欢迎读者的批评和指正,因为我知道我的观点可能并不完全正确,您的反馈将帮助我不断进步。如果我的笔记能给您带来哪怕是一点点的启示,我也会感到非常荣幸。同时,我也希望我的分享能够激发您的灵感和思考,让我们一起在编程的道路上不断前行~
接雨水
题目描述
给定 n 个非负整数表示每个宽度为 1 的柱子的高度图,计算按此排列的柱子,下雨之后能接多少雨水。

图片来源
提示
- n == height.length
- 1 <= n <= 2 * 104
- 0 <= height[i] <= 105
解决方案1:【动态规划】

通过观察图像,我们可以发现红色方框部分与木桶的形态颇为相似。让我们富有想象力地将最左侧高度为2的柱子视作木桶的左侧板,而将最右侧高度为3的柱子视作木桶的右侧板。基于深入人心的【木桶原理】,一个木桶的装水量总是受限于其最短的那块木板。这就意味着,木桶内的水柱高度+柱子高度与左侧板的高度相等时,即达到装水的极限。
更为精妙的是,对于图中的每个位置i,我们都可以将其左侧最高的柱子想象为木桶的左侧板,而将右侧最高的柱子视为木桶的右侧板。这样一来,每个位置的水柱高度+柱子高度height[i]之和,便取决于左侧板和右侧板中较低的那个,恰如木桶原理中所蕴含的深邃智慧。
问题1:对于每个位置i,如何获取其左侧最高柱子的高度left_max[i]和右侧最高柱子的高度right_max[i]呢?
可以通过两次遍历数组height进行获取,代码如下:
# 木桶理论
# 对于位置i,left_max[i]记录的是其左侧最高柱子的高度
left_max = [0] # 对于第0根柱子,其左侧没有柱子,默认其左侧最高柱子的高度为0
# 对于位置n-1-i,right_max[i]记录的是其右侧最高柱子的高度
right_max = [0] # 对于最后一根柱子,其右侧没有柱子,默认其右侧最高柱子的高度为0n = len(height)
# 顺序遍历
for i in range(1, n):# 对于位置i,left_max[-1]记录的是位置i-1其左侧最高柱子的高度---> 只需要和位置i-1的高度height[i-1]进行比较并取最大值即可得到位置i其左侧最高柱子的高度left_max.append(max(left_max[-1], height[i-1]))
# 逆序遍历
for i in range(n-2, -1, -1):# 对于位置i,right_max[-1]记录的是位置i+1其右侧最高柱子的高度---> 只需要和位置i+1的高度height[i+1]进行比较并取最大值即可得到位置i其右侧最高柱子的高度right_max.append(max(right_max[-1], height[i+1]))
# 因为是逆序遍历,需要将结果反转 ---> 反转后, right_max[i]记录的是位置i其右侧最高柱子的高度
right_max = right_max[::-1]# 验证结果
for i in range(n):print("对于第{}根柱子,其高度为{}, 其左侧最高的柱子高度是{},其右侧最高的柱子高度是{}".format(i, height[i], left_max[i], right_max[i]))
运行结果:

观察上图的输入height以及标准输出,可以发现算法成功获取到每个位置i的左侧最高柱子的高度left_max[i]和右侧最高柱子的高度right_max[i],有了这些已知条件后,对于每个位置i,我们可以通过min(left_max[i], right_max[i]) - height[i]得到位置i的水柱高度。
完整代码如下:
class Solution:def trap(self, height: List[int]) -> int:if not height:return 0# 木桶理论# 对于位置i,left_max[i]记录的是其左侧最高柱子的高度left_max = [0] # 对于第0根柱子,其左侧没有柱子,默认其左侧最高柱子的高度为0# 对于位置n-1-i,right_max[i]记录的是其右侧最高柱子的高度right_max = [0] # 对于最后一根柱子,其右侧没有柱子,默认其右侧最高柱子的高度为0n = len(height)# 顺序遍历for i in range(1, n):# 对于位置i,left_max[-1]记录的是位置i-1其左侧最高柱子的高度---> 只需要和位置i-1的高度height[i-1]进行比较并取最大值即可得到位置i其左侧最高柱子的高度left_max.append(max(left_max[-1], height[i-1]))# 逆序遍历for i in range(n-2, -1, -1):# 对于位置i,right_max[-1]记录的是位置i+1其右侧最高柱子的高度---> 只需要和位置i+1的高度height[i+1]进行比较并取最大值即可得到位置i其右侧最高柱子的高度right_max.append(max(right_max[-1], height[i+1]))# 因为是逆序遍历,需要将结果反转 ---> 反转后, right_max[i]记录的是位置i其右侧最高柱子的高度right_max = right_max[::-1]# 获取每个位置i的水柱高度total_rain = 0for i in range(n):water_height = min(left_max[i], right_max[i]) - height[i] # 水柱高度计算公式(根据木桶原理)if water_height > 0: # 水柱高度大于0才有意义total_rain += water_heightreturn total_rain
运行结果:

复杂度分析
- 时间复杂度:O(N),其中 N 是数组
height元素的数量。 - 空间复杂度:O(N)
- 需要存放每个位置左/右侧最高柱子的高度 ===> O(N)
结束语
- 亲爱的读者,感谢您花时间阅读我们的博客。我们非常重视您的反馈和意见,因此在这里鼓励您对我们的博客进行评论。
- 您的建议和看法对我们来说非常重要,这有助于我们更好地了解您的需求,并提供更高质量的内容和服务。
- 无论您是喜欢我们的博客还是对其有任何疑问或建议,我们都非常期待您的留言。让我们一起互动,共同进步!谢谢您的支持和参与!
- 我会坚持不懈地创作,并持续优化博文质量,为您提供更好的阅读体验。
- 谢谢您的阅读!
相关文章:
【LeetCode刷题笔记(8-1)】【Python】【接雨水】【动态规划】【困难】
文章目录 引言接雨水题目描述提示 解决方案1:【动态规划】结束语 接雨水 引言 编写通过所有测试案例的代码并不简单,通常需要深思熟虑和理性分析。虽然这些代码能够通过所有的测试案例,但如果不了解代码背后的思考过程,那么这些代…...
pycharm通过ssh连接远程服务器的docker容器进行运行和调试代码
pycharm连接远程服务器的docker容器通常有两种方法: 第一种:pycharm通过ssh连接已在运行中的docker容器 第二种:pycharm连接docker镜像,pycharm运行代码再自动创建容器 第一种方法比较通用简单,作者比较推崇。 条件…...
Chrome2023新版收藏栏UI改回旧版
版本 120.0.6099.109(正式版本)Chrome浏览器菜单新版、旧版的差异 想要将书签、功能内容改回旧版的朋友可以网址栏输入:「chrome://flags」,接着搜寻「Chrome Refresh 2023」。 最后将 Chrome Refresh 2023、Chrome Refresh 2023…...
WebSocket与JavaScript:实现实时获取位置
一、WebSocket介绍 WebSocket是一种在单个TCP连接上进行全双工通信的协议。与传统的HTTP请求相比,WebSocket能够在服务器和客户端之间建立持久连接,实现实时数据传输。WebSocket提供了较低的延迟和高效的数据传输。在实时舆情监测中,它能够实…...
一种解决Qt5发布release文件引发的无法定位程序输入点错误的方法
目录 本地环境问题描述分析解决方案 本地环境 本文将不会解释如何利用Qt5编译生成release类型的可执行文件以及如何利用windeployqt生成可执行的依赖库,请自行百度。 环境值操作系统Windows 10 专业版(22H2)Qt版本Qt 5.15.2Qt Creator版本5.0…...
UE4/UE5 日志插件(基于spdlog)
1 解决问题 对于高频日志序列化到本地的需求,spdlog肯定完美满足。 源码地址:https://github.com/gabime/spdlog 博主下载的版本为 spdlog-1.12.0,各位大佬可以根绝自己爱好选择。 2 过程介绍 大概目录: SpdlogLibC目录下是对…...
微信小程序ios中非cover组件点击重复触发地图tap事件
现象: map中使用view组件的click事件会重复触发地图的tap组件,只在ios上出现 <map id"maps" style"width: 100vw;height: 100vh;" :latitude"latitude" :longitude"longitude":markers"markers"…...
7.26 SpringBoot项目实战【还书】
文章目录 前言一、编写控制器二、编写服务层三、Git提交前言 本文是项目实战 业务接口 的最后一篇,上文 曾说过【还书】的 入口是【我的借阅记录】,因为【还书】是基于一次借阅记录而言,另外在4.2 数据库设计 曾分析过【还书】的业务场景,需要执行两步操作: 更新【借阅记…...
Golang中使用errors返回调用堆栈信息
Golang的errors包返回堆栈信息 标准库errors提供了处理错误的方法。比如常用的 func New(text string) error 用该方法处理错误信息,就只会输出自定义的 text 到控制台或者日志文件,没有其它辅助排查的信息输出,所以常规我们就只能根据 te…...
Web前端-HTML(常用标签)
文章目录 1. HTML常用标签1.1 排版标签1)标题标签h (熟记)2)段落标签p ( 熟记)3)水平线标签hr(认识)4)换行标签br (熟记)5)div 和 span标签(重点)6)排版标签总结 1.2 标签属性1.3 图像标签img (重点)1.4 链…...
一 OpenCV中的数据类型
1. cv::Mat 2. cv::Point 主要用来表示二维点,也有表示三维点的模板类型; cv::Point p(int, int) 最常用 ① cv::Point_<T> ② cv::Point2i cv::Point_<int> ③ cv::Point2f cv::Point_<float> ④ cv::Point2d …...
59. 螺旋矩阵 II(java实现,史上最详细教程,想学会的进!!!)
今天来分享一下螺旋矩阵的解题思路及代码的实现。 题目描述如下: 首先拿到这道题,首先不要慌张,我们来仔细分析一下会发现并没有那么难。 首先看下边界的元素是1、2、3递增的,那么我们也许可以根据这一点先把边界的元素一个一个给…...
vue 将后端返回的二进制流进行处理并实现下载
什么是二进制流文件? 二进制文件是一种计算机文件格式,它的数据以二进制形式存储,与文本文件不同。二进制文件可以包含任意类型的数据,例如图像、音频、视频、可执行文件、压缩文件等,而文本文件则仅仅包含 ASCII 码或…...
PyCharm连接远程服务器
要求:PyCharm专业版才支持远程服务 一、创建远程连接 先建立本地与远程服务器之间的SSH连接 1、配置连接 2、建立SSH连接,选择文件传输协议 SFTP 3、设置服务器名(可以随意命名) 4、配置 SSH连接 点击 172.18.1.202 配置…...
使用Qt制作网易云播放器的歌曲排行界面
!!!直接上图!!! !!!直接上图!!! !!!直接上图!!! 网易云排行榜…...
【.NET Core】特性(Attribute)详解
【.NET Core】特性(Attribute)详解 文章目录 【.NET Core】特性(Attribute)详解一、概述二、编写自定义属性2.1 自定义特性的主要步骤2.2 应用AttributeUsageAttributeAttributeTargets 成员Inherited属性AllowMultiple属性 三、声…...
【C++】POCO学习总结(十九):哈希、URL、UUID、配置文件、日志配置、动态库加载
【C】郭老二博文之:C目录 1、哈希 1.1 说明 std::map和std::set 的性能是:O(log n) POCO哈希的性能比STL容器更好,大约快两; POCO中对应std::map的是:Poco::HashMap; POCO中对应std::set的是 Poco::Hash…...
1846_安全SPI
Grey 全部学习内容汇总:GitHub - GreyZhang/g_embedded: some embedded basic knowledge. 1846_安全SPI SPI是一种常见的通信方式,在汽车电子中比较常用。但是如果涉及到安全相关的设计,可能得考虑更多。而SPI协议本身没有很好的标准化&am…...
SQL Server ,使用递归查询具有层级关系的数据。
假设我们有一个表格 Employees,其中包含员工的层级关系信息,每一行包括员工的ID、姓名以及上级员工的ID。 下面是一个示例表格及其数据: Employees ---------------------- EmployeeID | Name | ManagerID ---------------------- 1 …...
【参数汇总】mysql服务端/客户端常见优化参数
mysql服务端参数 1、innodb_buffer_pool_size (innodb索引buffer pool缓冲区大小) 默认大小为128M, 官方推荐其配置为系统内存的 50% 到 75% 。 一般innodb_buffer_pool_size要结合以下两个参数来设置: innodb_buffer_pool_ch…...
DeepSeek 赋能智慧能源:微电网优化调度的智能革新路径
目录 一、智慧能源微电网优化调度概述1.1 智慧能源微电网概念1.2 优化调度的重要性1.3 目前面临的挑战 二、DeepSeek 技术探秘2.1 DeepSeek 技术原理2.2 DeepSeek 独特优势2.3 DeepSeek 在 AI 领域地位 三、DeepSeek 在微电网优化调度中的应用剖析3.1 数据处理与分析3.2 预测与…...
反向工程与模型迁移:打造未来商品详情API的可持续创新体系
在电商行业蓬勃发展的当下,商品详情API作为连接电商平台与开发者、商家及用户的关键纽带,其重要性日益凸显。传统商品详情API主要聚焦于商品基本信息(如名称、价格、库存等)的获取与展示,已难以满足市场对个性化、智能…...
.Net框架,除了EF还有很多很多......
文章目录 1. 引言2. Dapper2.1 概述与设计原理2.2 核心功能与代码示例基本查询多映射查询存储过程调用 2.3 性能优化原理2.4 适用场景 3. NHibernate3.1 概述与架构设计3.2 映射配置示例Fluent映射XML映射 3.3 查询示例HQL查询Criteria APILINQ提供程序 3.4 高级特性3.5 适用场…...
【JVM】- 内存结构
引言 JVM:Java Virtual Machine 定义:Java虚拟机,Java二进制字节码的运行环境好处: 一次编写,到处运行自动内存管理,垃圾回收的功能数组下标越界检查(会抛异常,不会覆盖到其他代码…...
HTML 列表、表格、表单
1 列表标签 作用:布局内容排列整齐的区域 列表分类:无序列表、有序列表、定义列表。 例如: 1.1 无序列表 标签:ul 嵌套 li,ul是无序列表,li是列表条目。 注意事项: ul 标签里面只能包裹 li…...
Java毕业设计:WML信息查询与后端信息发布系统开发
JAVAWML信息查询与后端信息发布系统实现 一、系统概述 本系统基于Java和WML(无线标记语言)技术开发,实现了移动设备上的信息查询与后端信息发布功能。系统采用B/S架构,服务器端使用Java Servlet处理请求,数据库采用MySQL存储信息࿰…...
【电力电子】基于STM32F103C8T6单片机双极性SPWM逆变(硬件篇)
本项目是基于 STM32F103C8T6 微控制器的 SPWM(正弦脉宽调制)电源模块,能够生成可调频率和幅值的正弦波交流电源输出。该项目适用于逆变器、UPS电源、变频器等应用场景。 供电电源 输入电压采集 上图为本设计的电源电路,图中 D1 为二极管, 其目的是防止正负极电源反接, …...
基于PHP的连锁酒店管理系统
有需要请加文章底部Q哦 可远程调试 基于PHP的连锁酒店管理系统 一 介绍 连锁酒店管理系统基于原生PHP开发,数据库mysql,前端bootstrap。系统角色分为用户和管理员。 技术栈 phpmysqlbootstrapphpstudyvscode 二 功能 用户 1 注册/登录/注销 2 个人中…...
MFE(微前端) Module Federation:Webpack.config.js文件中每个属性的含义解释
以Module Federation 插件详为例,Webpack.config.js它可能的配置和含义如下: 前言 Module Federation 的Webpack.config.js核心配置包括: name filename(定义应用标识) remotes(引用远程模块࿰…...
从零手写Java版本的LSM Tree (一):LSM Tree 概述
🔥 推荐一个高质量的Java LSM Tree开源项目! https://github.com/brianxiadong/java-lsm-tree java-lsm-tree 是一个从零实现的Log-Structured Merge Tree,专为高并发写入场景设计。 核心亮点: ⚡ 极致性能:写入速度超…...
