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

文章目录

  • 引言
  • 接雨水
    • 题目描述
    • 提示
  • 解决方案1:【动态规划】
  • 结束语

接雨水

引言

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

接雨水

题目描述

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

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

提示

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

解决方案1:【动态规划】

图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)

结束语

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

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

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

相关文章

【扩散模型Diffusion Model系列】0-从VAE开始(隐变量模型、KL散度、最大化似然与AIGC的关系)

VAE VAE(Variational AutoEncoder)&#xff0c;变分自编码器&#xff0c;是一种无监督学习算法&#xff0c;被用于压缩、特征提取和生成式任务。相比于GAN(Generative Adversarial Network)&#xff0c;VAE在数学上有着更加良好的性质&#xff0c;有利于理论的分析和实现。 文…

C++指针

本文章对C指针的使用做一个全面的阐述与解释 1.1指针的定义使用 指针&#xff1a; 通过指针间接访问内存 指针就是地址 看下面代码&#xff1a; #include<iostream> using namespace std; int main(){//1、定义指针int * p;int a 10;//2、使用指针p &a;cout<…

STM32-02-STM32基础知识

文章目录 STM32基础知识1. STM32F103系统架构2. STM32寻址范围3. 存储器映射4. 寄存器映射 STM32基础知识 1. STM32F103系统架构 STM32F103 STM32F103是ST公司基于ARM授权Cortex M3内核而设计的一款芯片&#xff0c;而Cortex M内核使用的是ARM v7-M架构&#xff0c;是为了替代…

根据星历文件实现卫星的动态运行模拟matlab仿真

目录 1.算法运行效果图预览 2.算法运行软件版本 3.部分核心程序 4.算法理论概述 5.算法完整程序工程 1.算法运行效果图预览 2.算法运行软件版本 MATLAB2022a 3.部分核心程序 .................................................................................... % …

测试用例的修改更新

测试用例的修改更新是指测试过程中由于用户需求的改变&#xff0c;或者测试过程中发现有新的需求产生&#xff0c;使得测试用例需要进行修改。修改更新测试用例不仅是一种测试技术&#xff0c;更是一种质量保证的方法。但修改和更新测试用例的技术要点在于&#xff1a; 1、执行…

ReactHooks大全—useEffect

React Hooks是一种在函数组件中使用状态和生命周期等特性的方法。useEffect是其中一个常用的Hook&#xff0c;它可以让你在组件渲染后执行一些副作用操作&#xff0c;比如发送网络请求、订阅事件、修改DOM等。在本文中&#xff0c;我们将介绍useEffect的基本使用、实现原理、最…

Note3---初阶二叉树~~

目录​​​​​​​ 前言&#x1f344; 1.树概念及结构☎️ 1.1 树的概念&#x1f384; 1.2 树的相关概念&#x1f99c; 1.2.1 部分概念的加深理解&#x1f43e; 1.2.2 树与非树&#x1fab4; 1.3 树的表示&#x1f38b; 1.4 树在实际中的运用&#xff08;表示文件系统…

[Onnx简化库深度剖析] OnnxSimplifier和OnnxOptimizer解读-(2)

[Onnx简化库深度剖析] OnnxSimplifier和OnnxOptimizer解读-(2) 简介 上篇重点介绍了OnnxSimplifier的库&#xff0c;其中的FixedPointFn迭代优化函数利用到了OnnxOptimizer这个官方的优化库&#xff0c;大部分的优化细节是在OnnxOptimizer内的。因此本篇重点介绍一下OnnxOpti…

飞天使-docker知识点12-docker-compose

文章目录 docker-compose命令启动单个容器重启容器停止和启动容器停止和启动所有容器演示一个简单示范 docker-compose 部署有依赖问题 Docker Compose 是一个用于定义和运行多容器 Docker 应用程序的工具。它允许您使用简单的 YAML 文件来配置应用程序的服务、网络和存储等方…

全志V3s之NFS连接ubuntu22.04

1、问题一&#xff1a; [ 100.329728] VFS: Unable to mount root fs via NFS, trying floppy. [ 100.336262] VFS: Cannot open root device "nfs" or unknown-block(2,0): error -6 [ 100.343580] Please append a correct "root" boot option; here…

RT-Smart elf 动态加载技术 : 开启 ldso 动态加载

前言 RT-Smart,类似于Linux,可以动态的加载运行 应用程序 elf 文件 应用程序 elf 文件,有的是静态链接编译的,有的是动态链接编译的,动态链接编译的,还需要加载 动态共享库 (.so) 本篇讲解一下 RT-Smart 上 elf 动态加载功能的实现,顺便讲一下动态加载的原理 环境搭建 R…

12.18

有道云笔记 机械臂 #include <myhead.h> #define SERPORT 8822 #define SERIP "192.168.125.61" #define PORT 6666 #define IP "192.168.125.88" int main(int argc, const char *argv[]) {int cfd-1;if((cfdsocket(AF_INET,SOCK_STREAM,0))-1){p…

RTrPPG

研究背景 心率 (HR) 和脉搏率变异性 (PRV) 是允许分析心脏行为的两个生理参数。心率监测可以通过接触式和非接触式的两种方法进行。通常用于测量 HR 和 PRV 的两种接触式技术是心电图 (ECG) 和光电容积脉搏波 (PPG)。 ECG 测量由心脏活动引起的电场。另一方面&#xff0c;PPG …

02什么是CPU上下文切换

上⼀节&#xff0c; 讲了要怎么理解平均负载&#xff08; Load Average&#xff09; &#xff0c; 并⽤三个案例展示了不同场景下平均负载升⾼的分析⽅法。 这其中&#xff0c; 多个进程竞争 CPU 就是⼀个经常被我们忽视的问题。 1、CPU上下文切换的概念 我想你⼀定很好奇&am…

2023/12/18 work

1. 机械臂 #include <stdio.h> #include <string.h> #include <stdlib.h> #include <myhead.h>#define CLI_PORT 6667 //本机的端口号 #define CLI_IP "192.168.125.79" //本机的IP#define SER_PORT 8888 //服务器的端口号 #define…

智能家居和智能家居控制设备有什么区别?

智能家居和智能家居控制设备在功能和用途伤的区别&#xff1a; 智能家居是一种整体的概念&#xff0c;它涵盖了整个家庭环境的智能化&#xff0c;包括智能家电、智能照明、智能安防等设备的互联互通和协同工作。智能家居的目标是通过中央控制器或智能音箱等设备&#xff0c;实现…

瑞安籍侨领池万进荣任意大利瑞安同乡总会第五届会长

浙江温州瑞安是全国重点侨乡&#xff0c;拥有海外侨胞16万人、侨领2100多名、归侨侨眷近12万人&#xff0c;在世界100多个国家和地区建有70多个侨团组织。 意大利瑞安同乡总会第五届理事会会长团全体成员 青年部全体成员 各兄弟会长及代表 12月10日&#xff0c;意大利瑞安同乡…

LabVIEW在燃气轮机发电机组励磁控制系统测试中的应用

LabVIEW在燃气轮机发电机组励磁控制系统测试中的应用 燃气轮机发电机组作为一种高效可靠的常备应急电源&#xff0c;在保障发电品质稳定性和可靠性方面发挥着关键作用。其中&#xff0c;励磁控制系统是保证供电质量的重要环节&#xff0c;对发电机组的稳定运行至关重要。为了有…

渲染函数JSX

大多数情况使用vue模板语法创建应用&#xff0c;在某些场景下&#xff0c;需要用到JavaScript完全的编程能力&#xff0c;这时就用到渲染函数了。 基本用法 创建Vnodes Vue提供了一个h()函数用于创建vnodes&#xff1a; import {h} from vueconst vnode h(div, // type{ i…

档案数字化管理可以提供什么服务?

档案数字化管理提供了便捷、高效和安全的档案管理服务&#xff0c;帮助组织更好地管理和利用自己的档案资源。 具体来说&#xff0c;专久智能档案数字化管理可以提供以下服务&#xff1a; 1. 档案扫描和数字化&#xff1a;将纸质档案通过扫描仪转换为数字格式&#xff0c;包括文…