当前位置: 首页 > news >正文

力扣第42题 接雨水

前言

记录一下刷题历程 力扣第42题 接雨水


接雨水

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

示例 1:在这里插入图片描述

输入:height = [0,1,0,2,1,0,1,3,2,1,2,1]
输出:6
解释:上面是由数组 [0,1,0,2,1,0,1,3,2,1,2,1] 表示的高度图,在这种情况下,可以接 6 个单位的雨水(蓝色部分表示雨水)。
示例 2:

输入:height = [4,2,0,3,2,5]
输出:9

分析

我们首先可以想到的就是统计一列左边和右边所有柱子的最高高度,根据下图我们可以知道左右最高高度较低的值与当前柱子的高度差就是这一列能存储的水的高度。这是第一种方法但是需要O(n)的空间复杂度,有没有优化空间呢,我们来看方法2.
在这里插入图片描述
第二种方法,我们其实并不需要同时计算左右两边的最高高度,假如说我们对于当前列已经知道了左侧的最高高度,只要右侧出现比左侧高度还要高,那么左侧的最高高度就一定是水体的顶部,然后我们可以计算该列的水体高度,我们从数组两端向中间遍历,分别计算左指针和左侧最高高度,右指针和右侧最高高度,找到对应结果较低的那一列直接更新结果即可

代码如下:

第一种方法:

class Solution {
public:// 接收一个整数数组 height,表示每个柱子的高度,返回可以接住的雨水总量int trap(vector<int>& height) {// n 表示柱子的总数int n = height.size();// res 用于存储最终结果,也就是可以接住的雨水总量int res = 0;// 创建两个数组,分别存储每个位置的左边最高柱子和右边最高柱子vector<int> leftMax(n);  // leftMax[i] 表示位置 i 左边最高的柱子vector<int> rightMax(n); // rightMax[i] 表示位置 i 右边最高的柱子// 初始化 leftMax 数组的第一个元素,因为第 0 个位置没有左边的柱子,所以 leftMax[0] 就是 height[0]leftMax[0] = height[0];// 计算每个位置的左边最高柱子,从左到右遍历for(int i = 1; i < n - 1; i++) {// leftMax[i] 是当前位置 i 和位置 i-1 的最高柱子之间的较大值leftMax[i] = max(leftMax[i - 1], height[i]);}// 初始化 rightMax 数组的最后一个元素,因为最后一个位置没有右边的柱子,所以 rightMax[n-1] 就是 height[n-1]rightMax[n - 1] = height[n - 1];// 计算每个位置的右边最高柱子,从右到左遍历for(int i = n - 2; i > 0; i--) {// rightMax[i] 是当前位置 i 和位置 i+1 的最高柱子之间的较大值rightMax[i] = max(rightMax[i + 1], height[i]);}// 遍历每个柱子,计算该柱子上方能够接住的雨水for(int i = 1; i < n - 1; i++) {// 当前位置的雨水容量等于左边和右边最高柱子之间的较小值减去当前柱子的高度int capacity = min(leftMax[i], rightMax[i]) - height[i];// 累加结果,capacity 是该位置能接住的水res += capacity;}// 返回最终的接水量return res;}
};

第二种方法:

class Solution {
public:int trap(vector<int>& height) {// 获取柱子的总数int n = height.size();// 如果柱子数小于3,无法接住雨水,直接返回0if (n < 3) return 0;// 结果变量,用于存储接住的雨水总量int res = 0;// 左指针初始化为数组的起始位置int left = 0;// 右指针初始化为数组的结束位置int right = n - 1;// 左边最大值初始化为0int leftMax = 0;// 右边最大值初始化为0int rightMax = 0;// 双指针遍历,直到两个指针重合while (left < right) {// 更新左边最大值leftMax = max(leftMax, height[left]);// 更新右边最大值rightMax = max(rightMax, height[right]);// 如果左边最大值小于右边最大值,处理左边的情况if (leftMax < rightMax) {// 当前位置的水量 = 左边最大值 - 当前柱子的高度res += leftMax - height[left];// 左指针向右移动left++;} // 如果右边最大值小于等于左边最大值,处理右边的情况else {// 当前位置的水量 = 右边最大值 - 当前柱子的高度res += rightMax - height[right];// 右指针向左移动right--;}}// 返回接住的雨水总量return res;}
};

代码解释

第一种方法主要思路:

1.对于每个柱子而言,能接住的水量取决于左边最高的柱子和右边最高的柱子,以及当前位置柱子的高度。柱子能接住的水量是左、右柱子中较矮的那个减去当前柱子的高度。

为了快速得到每个柱子左边和右边的最大值,我们通过预处理分别计算 leftMax 和 rightMax 数组。然后对于每个柱子,计算它上方可以接住的水量并累加到结果中。

2.首先,我们用两个数组 leftMax 和 rightMax 分别记录每个柱子左边和右边的最高柱子。

leftMax[i] 表示位置 i 左边的最高柱子,包括 i 本身。
rightMax[i] 表示位置 i 右边的最高柱子,包括 i 本身。

3.遍历 height 数组计算每个位置的左边最高值和右边最高值。

对于每个位置的柱子,我们计算其能接住的雨水量:min(leftMax[i], rightMax[i]) - height[i]。
累加每个位置的水量得到最终结果。

复杂度分析:

时间复杂度:该算法需要遍历三次数组,时间复杂度为 O(n)。
空间复杂度:需要额外的两个数组存储左边和右边的最大值,空间复杂度为 O(n)。
这就是该算法的基本思路和实现方式。

第二种方法主要思路:

1.初始化:

获取 height 数组的大小 n,存储在变量 n 中。
如果柱子的数量小于3(例如0、1或2个柱子),无法形成凹槽来接雨水,直接返回0。
初始化结果变量 res 为0,用于存储计算得到的雨水总量。
初始化两个指针 left 和 right 分别指向数组的起始和结束位置。
初始化 leftMax 和 rightMax 为0,用于记录当前左边和右边的最大高度。

2.双指针遍历:

当 left 指针小于 right 指针时进行循环。
在每次循环中:
更新 leftMax 为当前位置左指针所指柱子的高度与之前 leftMax 的最大值之间的较大值。
更新 rightMax 为当前位置右指针所指柱子的高度与之前 rightMax 的最大值之间的较大值。

如果 leftMax 小于 rightMax,说明左边的最高柱子更矮,处理左边的情况:

计算当前位置可以接住的雨水量,等于 leftMax 减去当前柱子的高度。
将该雨水量累加到结果变量 res 中。
将左指针向右移动一位。

否则,说明右边的最高柱子更矮或相等,处理右边的情况:

计算当前位置可以接住的雨水量,等于 rightMax 减去当前柱子的高度。
将该雨水量累加到结果变量 res 中。
将右指针向左移动一位。

3.返回结果:

循环结束后,返回最终计算得到的接水总量 res。

复杂度分析

时间复杂度:该算法的时间复杂度为 O(n),因为每个柱子位置在循环中只会被访问一次。
空间复杂度:该算法的空间复杂度为 O(1),仅使用了常量级的额外空间,不需要额外的数组。
这个双指针方法在时间复杂度和空间复杂度上都具有较好的性能,是处理这个问题的一种高效解法。

相关文章:

力扣第42题 接雨水

前言 记录一下刷题历程 力扣第42题 接雨水 接雨水 原题目&#xff1a;给定 n 个非负整数表示每个宽度为 1 的柱子的高度图&#xff0c;计算按此排列的柱子&#xff0c;下雨之后能接多少雨水。 示例 1&#xff1a; 输入&#xff1a;height [0,1,0,2,1,0,1,3,2,1,2,1] 输出&…...

轻松录制每一刻:探索2024年免费高清录屏应用

你不会还在用一些社交工具来录屏吧&#xff1f;现在的市面上有不少免费录屏的软件了。别看如软件是免费的&#xff0c;它的功能比起社交工具的录屏功能来说全面的多。这次我就分享几款我用过的录屏工具。 1.福晰录屏大师 链接直达&#xff1a;https://www.foxitsoftware.cn/R…...

【小沐学OpenGL】Ubuntu环境下glfw的安装和使用

文章目录 1、简介1.1 OpenGL简介1.2 glfw简介 2、安装glfw2.1 直接命令二进制安装2.2 源码安装 3、测试glfw3.1 测试1&#xff0c;glfwglew3.2 测试2&#xff0c;glfwglad3.3 测试3 结语 1、简介 1.1 OpenGL简介 OpenGL作为图形界的工业标准&#xff0c;其仅仅定义了一组2D和…...

[数据集][目标检测]汽油检泄漏检测数据集VOC+YOLO格式237张2类别

数据集格式&#xff1a;Pascal VOC格式YOLO格式(不包含分割路径的txt文件&#xff0c;仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件) 图片数量(jpg文件个数)&#xff1a;237 标注数量(xml文件个数)&#xff1a;237 标注数量(txt文件个数)&#xff1a;237 标注类别…...

图文解析保姆级教程:Postman专业接口测试工具的安装和基本使用

文章目录 1. 引入2. 介绍3. 安装4. 使用 此教程摘选自我的笔记&#xff1a;黑马JavaWeb开发笔记16——请求&#xff08;postman、简单参数、实体参数、RequestParam映射&#xff09;想要详细了解更多有关请求各种参数介绍的知识可以移步此篇笔记。 1. 引入 在当前最为主流的开…...

jenkins配置流水线

新建任务&#xff0c;随便选一个名字&#xff0c;选中流水线 配置git的用户名和密码&#xff0c;记录ID&#xff0c;后面配置流水线的时候用。 pipeline {agent anystages {stage(stop app){steps {script {def remote [:]//配置服务地址&#xff0c;用户名和密码remote.na…...

SQL 编程基础

SQL&#xff08;结构化查询语言&#xff09;广泛应用于数据库操作&#xff0c;是每个程序员都需要掌握的技能之一。这篇文章将带你从基础入门&#xff0c;了解SQL编程中的常量、变量及流程控制语句。我们将采用简单易懂的语言&#xff0c;结合实际示例&#xff0c;帮助你轻松理…...

sql 中名字 不可以 包含 mysql中 具有 特定意义 的单词

这种sql执行不报错 这种sql执行报错 所以sql中名字不可以使用mysql中具有特定意义的单词 以此文章作为警告&#xff0c;我下次起名字不可以使用 mysql中具有特殊意义的字符 就因为这个导致我搞了一个多小时&#xff0c;急死我了&#xff0c;周五就要前后端联调了。下次千万不…...

分布式部署①

&#x1f4d1;打牌 &#xff1a; da pai ge的个人主页 &#x1f324;️个人专栏 &#xff1a; da pai ge的博客专栏 ☁️宝剑锋从磨砺出&#xff0c;梅花香自苦寒来 1. 需要部署的服务 Nacos 理论上,应…...

开源可视化大屏superset Docker环境部署

superset 开源可视化大屏Docker环境部署 前言 superset是俄罗斯开源的一款可视化大屏&#xff0c;用于数据可视化探索&#xff0c;含有丰富的图表组件&#xff0c;可以支持接入各种数据源。 接触superset就是想体验下可视化大屏功能&#xff0c;想最快速度安装成功&#xff…...

tomato靶场通关攻略

1.御剑2014找到IP地址 2.dirb扫描目录 3.再次详细扫描目录 4.访问找到的目录文件 进入antibots中 5.搜寻一会再info.php里面发现有东西 6.这个地方貌似可以进行利用 7.查看源代码发现包含include文件上传漏洞 8.网址后面跟?image../../../../../../../etc/passwd 9.既然可以查…...

【Spring Boot 3】【Web】处理跨域资源共享 CORS

【Spring Boot 3】【Web】处理跨域资源共享 CORS 背景介绍开发环境开发步骤及源码工程目录结构总结背景 软件开发是一门实践性科学,对大多数人来说,学习一种新技术不是一开始就去深究其原理,而是先从做出一个可工作的DEMO入手。但在我个人学习和工作经历中,每次学习新技术…...

HUAWEI华为MateBook B5-420 i5 集显(KLCZ-WXX9,KLCZ-WDH9)原装出厂Windows10系统文件下载

适用型号&#xff1a;KLCZ-WXX9、KLCZ-WDH9 链接&#xff1a;https://pan.baidu.com/s/12xnaLtcPjZoyfCcJUHynVQ?pwdelul 提取码&#xff1a;elul 华为原装系统自带所有驱动、出厂主题壁纸、系统属性联机支持标志、系统属性专属LOGO标志、华为浏览器、Office办公软件、华为…...

算法练习题10:leetcode76最小覆盖子串-滑动窗口

目录 题目 题目描述 约束条件 解决思路 代码 getOrDefault(c, 0) 方法 方法签名 参数 返回值 示例 getOrDefault 与 get 的主要区别 Integer 题目 题目描述 给定两个字符串 s 和 t&#xff0c;请你在字符串 s 中找到包含 t 中所有字符的最小子串。 要求&#xf…...

Svn常用操作技巧详细说明

TortoiseSVN是一个Windows操作系统下的Subversion客户端&#xff0c;它为用户提供了直观易用的界面&#xff0c;方便进行版本控制操作。下面是一些TortoiseSVN的常用操作技巧的详细说明&#xff1a; 检出代码&#xff1a; 在Windows资源管理器中&#xff0c;选择一个空文件夹&a…...

六、MySQL高级—架构介绍(1)

&#x1f33b;&#x1f33b; 目录 一、Mysql 简介1.1 概述1.2 Mysql 高手是怎样炼成的 二、Mysql Linux 版的安装2.1 mysql5.52.2 mysql5.7 三、Mysql 的用户与权限管理3.1 MySQL的用户管理3.2 权限管理3.3 通过工具远程访问 四、 Mysql的一些杂项配置(了解)五、 Mysql 逻辑架构…...

TensorRT-For-YOLO-Series项目:实现yolov10模型的python-tensorrt推理(对比int8与fp16推理差异)

项目地址&#xff1a;https://github.com/Linaom1214/TensorRT-For-YOLO-Series/tree/cuda-python 算法支持状态&#xff1a; 2024.6.16 Support YOLOv9, YOLOv10, changing the TensorRT version to 10.0 2023.8.15 Support cuda-python 2023.5.12 Update 2023.1.7 support YO…...

码上君量化互助社群介绍

写在前面 量化投资是一个漫长的过程&#xff0c;一个人单打独斗会走很多弯路&#xff0c;所以建立一个交流沟通互助群是有必要的。 无论是加入我的这个量化互助社群&#xff0c;还是加入其他的社群&#xff0c;首先要想想自己加入社群的目的是什么&#xff0c;自己想从中获得…...

Qt使用小技巧之按钮动态变化

前言 最近写小demo中无意发现的&#xff0c;是想实现当鼠标悬停到按钮上面的时候&#xff0c;按钮实现动态变化&#xff0c;让人知道鼠标经过了按钮&#xff0c;效果如下 hoverDynamicPushButton 正文 首先是将按钮的边框给去掉&#xff0c;然后设置下它的悬停伪状态就行了 格…...

MySQL——事务与存储过程(三)存储过程的使用(1)调用存储过程

使用存储过程可以使程序执行效率更高、安全性更好&#xff0c;增强程序的可重用性和维护性。接下来将针对存储过程的使用进行详细的讲解。 存储过程有多种调用方法。存储过程必须使用CALL语句调用&#xff0c;并且存储过程和数据库相关&#xff0c;如果要执行其他数据库…...

HTML 语义化

目录 HTML 语义化HTML5 新特性HTML 语义化的好处语义化标签的使用场景最佳实践 HTML 语义化 HTML5 新特性 标准答案&#xff1a; 语义化标签&#xff1a; <header>&#xff1a;页头<nav>&#xff1a;导航<main>&#xff1a;主要内容<article>&#x…...

Prompt Tuning、P-Tuning、Prefix Tuning的区别

一、Prompt Tuning、P-Tuning、Prefix Tuning的区别 1. Prompt Tuning(提示调优) 核心思想:固定预训练模型参数,仅学习额外的连续提示向量(通常是嵌入层的一部分)。实现方式:在输入文本前添加可训练的连续向量(软提示),模型只更新这些提示参数。优势:参数量少(仅提…...

PPT|230页| 制造集团企业供应链端到端的数字化解决方案:从需求到结算的全链路业务闭环构建

制造业采购供应链管理是企业运营的核心环节&#xff0c;供应链协同管理在供应链上下游企业之间建立紧密的合作关系&#xff0c;通过信息共享、资源整合、业务协同等方式&#xff0c;实现供应链的全面管理和优化&#xff0c;提高供应链的效率和透明度&#xff0c;降低供应链的成…...

java 实现excel文件转pdf | 无水印 | 无限制

文章目录 目录 文章目录 前言 1.项目远程仓库配置 2.pom文件引入相关依赖 3.代码破解 二、Excel转PDF 1.代码实现 2.Aspose.License.xml 授权文件 总结 前言 java处理excel转pdf一直没找到什么好用的免费jar包工具,自己手写的难度,恐怕高级程序员花费一年的事件,也…...

汽车生产虚拟实训中的技能提升与生产优化​

在制造业蓬勃发展的大背景下&#xff0c;虚拟教学实训宛如一颗璀璨的新星&#xff0c;正发挥着不可或缺且日益凸显的关键作用&#xff0c;源源不断地为企业的稳健前行与创新发展注入磅礴强大的动力。就以汽车制造企业这一极具代表性的行业主体为例&#xff0c;汽车生产线上各类…...

高危文件识别的常用算法:原理、应用与企业场景

高危文件识别的常用算法&#xff1a;原理、应用与企业场景 高危文件识别旨在检测可能导致安全威胁的文件&#xff0c;如包含恶意代码、敏感数据或欺诈内容的文档&#xff0c;在企业协同办公环境中&#xff08;如Teams、Google Workspace&#xff09;尤为重要。结合大模型技术&…...

04-初识css

一、css样式引入 1.1.内部样式 <div style"width: 100px;"></div>1.2.外部样式 1.2.1.外部样式1 <style>.aa {width: 100px;} </style> <div class"aa"></div>1.2.2.外部样式2 <!-- rel内表面引入的是style样…...

Webpack性能优化:构建速度与体积优化策略

一、构建速度优化 1、​​升级Webpack和Node.js​​ ​​优化效果​​&#xff1a;Webpack 4比Webpack 3构建时间降低60%-98%。​​原因​​&#xff1a; V8引擎优化&#xff08;for of替代forEach、Map/Set替代Object&#xff09;。默认使用更快的md4哈希算法。AST直接从Loa…...

Kafka主题运维全指南:从基础配置到故障处理

#作者&#xff1a;张桐瑞 文章目录 主题日常管理1. 修改主题分区。2. 修改主题级别参数。3. 变更副本数。4. 修改主题限速。5.主题分区迁移。6. 常见主题错误处理常见错误1&#xff1a;主题删除失败。常见错误2&#xff1a;__consumer_offsets占用太多的磁盘。 主题日常管理 …...

HTML前端开发:JavaScript 获取元素方法详解

作为前端开发者&#xff0c;高效获取 DOM 元素是必备技能。以下是 JS 中核心的获取元素方法&#xff0c;分为两大系列&#xff1a; 一、getElementBy... 系列 传统方法&#xff0c;直接通过 DOM 接口访问&#xff0c;返回动态集合&#xff08;元素变化会实时更新&#xff09;。…...