力扣(leetcode) 42. 接雨水 (带你逐步思考)

力扣(leetcode) 42. 接雨水 (带你逐步思考)

链接:https://leetcode.cn/problems/trapping-rain-water/

难度:hard

给定 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

提示:

  • n == height.length
  • 1 <= n <= 2 * 10^4
  • 0 <= height[i] <= 10^5

思路:

  1. 观察能接雨水的容器的形状,可以发现容器必是两边高,中间低
  2. 再来单独看每根柱子,一根柱子上是否有水,就得看他是否处于这样一个两边高,中间低的地势。
  3. 如何判断?看柱子左右两边是否有比他高的柱子,只要求出左右两边的最高柱子就可以快速判断。
  4. 接水的多少如何计算?一个木桶能接多少水取决于最短的那块板,即左右两边较矮的那根柱子高度决定当前柱子的接水高度。min(leftmax,rightmax)-height[i]

实现:

主要需要实现快速对leftmax和rightmax的求解,这个十分简单,从左到右,从右到左各一次遍历就可以求出。将结果存放到数组里后续使用即可降低时间复杂度。

代码:

class Solution {
public:int trap(vector<int>& height) {int n=height.size();int total=0;vector<int> rightmax(n);rightmax[n-1]=height.back();for(int i=n-2;i>=0;i--)rightmax[i]=max(rightmax[i+1],height[i]);int leftmax=height[0];for(int i=1;i<n-1;i++){int a = min(leftmax,rightmax[i+1]);if(a>height[i])total+= a-height[i];leftmax=max(leftmax,height[i]);	#leftmax与当前柱子的遍历同步求出,不开数组,节省空间}return total;}
};

这里由于需要保存rightmax,消耗了O(n)的内存,有没有更节省空间的方法?

双指针

我们注意到,要去求每个柱子接水的多少只需要知道leftmax和rightmax里较矮的那一个就行了。也就是说,我们只要知道左边右边哪一个更矮,并且知道它的高度,另一边的高度就算不知道也没关系(···线索条件···)。

我们考虑对刚刚的leftmax和rightmax的求解进行优化,leftmax和rightmax分别是通过从左到右从右到左的遍历(扫描)来求解的。那么我们思考能否利用线索条件来简化扫描。

考虑当前柱子的其中一边已经被扫描完的情况(假设为左边),那么右边的扫描其实并不需要完全扫描,只要扫描到有一根柱子的高度比左边的最高还要高就可以停止了,见下图所示:

在这里插入图片描述

在理解了上述过程的情况下。我们引入双指针,左右两边各一根指针,同时向中间扫描。那么在某一时刻,对于两边已完成扫描的区域,我们是可以知道哪边的最高更矮的:

在这里插入图片描述

那么贴近更矮的那边的下一个被扫描到的柱子的接水高度就可以被确定了(图中黄色箭头所指的位置)。现在,箭头所指位置的接水量已经确定了,左边就可以接着往下扫描,同时更新leftmax,然后将leftmax和rightmax进行新一轮的对比,哪边较小,就让箭头指向哪边的下一个扫描位置,重复这一过程就可以让黄色箭头经过所有的柱子。

代码:

class Solution {
public:int trap(vector<int>& height) {int leftmax=height.front(),rightmax=height.back();int total=0;int left=0,right=height.size()-1;while(left+1<right){if(leftmax<rightmax){total+=leftmax-height[++left]>0?leftmax-height[left]:0;leftmax=max(leftmax,height[left]);}else{total+=rightmax-height[--right]>0?rightmax-height[right]:0;rightmax=max(rightmax,height[right]);}}return total;}
};

如果对你有帮助,不妨点个赞b( ̄▽ ̄)d

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

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

相关文章

鸿蒙开发踩坑与理解

基于 studio dev3.1,api 9 总结:现在的鸿蒙,感觉就像是用eclipse开发android的时候的android4.0或者4.0以下 持续更新中… 申请next,可能没通过? 没下文了。可能华为还不希望普通开发者进行开发吧。 兼容性问题 鸿蒙4.0,华为mate40E当前版本有黑屏、卡顿问题,客服说a…

【正点原子Linux连载】 第三十三章 Linux CAN驱动实验 摘自【正点原子】ATK-DLRK3568嵌入式Linux驱动开发指南

1&#xff09;实验平台&#xff1a;正点原子ATK-DLRK3568开发板 2&#xff09;平台购买地址&#xff1a;https://detail.tmall.com/item.htm?id731866264428 3&#xff09;全套实验源码手册视频下载地址&#xff1a; http://www.openedv.com/docs/boards/xiaoxitongban 第三十…

Word目录格式的编辑记录

1、整体风格 鼠标右键&#xff0c;编辑域 选择目录&#xff0c;风格可以根据自己的喜好选择古典、优雅、正式等 2、字段、段落样式调整 更新整个目录 加载出样式侧框&#xff0c;选中某一级目录&#xff0c;侧框会定位到其样式 然后修改对应的样式&#xff0c;比如字体和段…

vscode自动生成返回值的快捷键

vscode中类似idea的altenter功能&#xff0c;可以添加返回值 idea中是Introduce local variable&#xff0c; vscode中按下command.(句号) 然后选extract to local variable或者 Assign statement to new local variable都行&#xff0c; 光标在分号前如图&#xff1a; 光标在…

探索直播+电商系统中台架构:连接消费者与商品的智能纽带

随着直播电商的崛起&#xff0c;电商行业进入了全新的智能时代。直播形式的互动性和即时性为消费者提供了全新的购物体验&#xff0c;而电商平台则为商品的展示、销售和配送提供了强大的支持。在这一背景下&#xff0c;直播电商系统中台架构成为了连接消费者与商品的智能纽带&a…

Java基于微信小程序的电影院订票系统,附源码

博主介绍&#xff1a;✌IT徐师兄、7年大厂程序员经历。全网粉丝15W、csdn博客专家、掘金/华为云//InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专栏推荐订阅&#x1f447;&#x1f3…

C语言简单的数据结构:双向链表的实现

目录&#xff1a; 1.双向链表的结构和初始化1.1双向链表的结构1.2双向链表的初始化 2.双向链表的相关操作2.1双向链表的尾插、打印和头插2.11双向链表的尾插2.12双向链表的打印2.13双向链表的头插 2.2双向链表的尾删和头删2.21双向链表的尾删2.22双向链表的头删 2.3双向链表查找…

前后端系统开发之——文章管理

原文地址&#xff1a;前后端系统开发之——文章管理 - Pleasure的博客 下面是正文内容&#xff1a; 前言 主要使用的技术&#xff1a;前端使用的是Vue.js&#xff0c;后端使用的是SpringBoot。如不雷同可以直接跳过了。 文章管理是这个系统最主要的一个功能也是最常规的一个功…

如何寻找可靠的第三方软件检测机构

随着科技的飞速发展和数字化进程的加速&#xff0c;软件质量成为了企业竞争的关键。为了确保软件的质量和性能&#xff0c;许多企业选择寻找第三方的软件检测机构来进行软件的质量控制和评估。那么&#xff0c;如何找到一家可靠的第三方软件检测机构呢&#xff1f; 1.明确检测…

怎么设置启用远程桌面? 如何让外网电脑远程本地内网?

如何远程控制电脑&#xff1f;最简单实用的方案是开启电脑系统自带的远程桌面功能&#xff0c;如果涉及跨网、内外网互通&#xff0c;可以同时用快解析内网映射外网。下面是方案的具体实施步骤&#xff0c;供大家参考。 怎么打开设置启用远程桌面&#xff1f; 1.在目标需要远…

05—js对象

一、初识对象 JavaScript是面向对象编程&#xff08;Object Oriented Programming&#xff0c;OOP&#xff09;语言。 面对象是一种复合值&#xff1a;它将很多值集合在一起&#xff0c;可通过名字访问这些值。对象也可看做一种无序的数据集合&#xff0c;由若干个“键值对”…

数据库--Sqlite3

1、思维导图 2sqlite3在linux中是实现数据的增删&#xff0c;改 #include<myhead.h> int main(int argc, const char *argv[]) { //1、定义一个数据库句柄指针 sqlite3* ppDb NULL; //2、创建或打开数据库 if(sqlite3_open("./mydb…

通过两道题理解哈夫曼树

哈夫曼树定义 哈夫曼树&#xff08;Huffman Tree&#xff09;&#xff0c;又称最优二叉树&#xff0c;是一种带权路径长度最短的二叉树。所谓带权路径长度是指树中所有的叶子结点的权值乘以其到根结点的路径长度&#xff08;边数&#xff09;。哈夫曼树广泛应用于数据压缩等领…

Centroid-Aware Feature Recalibration for Cancer Grading in Pathology Images论文速读

Centroid-Aware Feature Recalibration for Cancer Grading in Pathology Images 摘要 癌症分级是病理学中的一项重要任务。人工神经网络在计算病理学领域的最新发展表明&#xff0c;这些方法在提高癌症诊断的准确性和质量方面具有巨大潜力。然而&#xff0c;这些方法的稳健性…

面试官最怕你懂的Kafka面试题,一招致胜!

&#x1f469;&#x1f3fd;‍&#x1f4bb;个人主页&#xff1a;阿木木AEcru &#x1f525; 系列专栏&#xff1a;《Docker容器化部署系列》 《Java每日面筋》 &#x1f4b9;每一次技术突破&#xff0c;都是对自我能力的挑战和超越。 目录 一、前言Kafka的优点Kafka的使用场景…

密码学 | 椭圆曲线密码学 ECC 入门(二)

目录 4 椭圆曲线&#xff1a;更好的陷门函数 5 奇异的对称性 6 让我们变得奇特 ⚠️ 原文地址&#xff1a;A (Relatively Easy To Understand) Primer on Elliptic Curve Cryptography ⚠️ 写在前面&#xff1a;本文属搬运博客&#xff0c;自己留着学习。如果你和我一样…

实力认证!亚数产品入选《中国网络安全行业全景图(第十一版)》

2024年4月12日&#xff0c;安全牛第十一版《中国网络安全行业全景图》&#xff08;以下简称“全景图”&#xff09;正式发布。 亚数信息科技&#xff08;上海&#xff09;有限公司&#xff08;以下简称“亚数”&#xff09;成功入选数字证书、加解密、密钥管理三项细分领域。 此…

Linux 2.进程(守护进程)

守护进程 何谓守护进程常见守护进程进程查看命令pskill命令编写简单守护进程守护进程的父进程 何谓守护进程 daemon&#xff0c;表示守护进程&#xff0c;简称为d&#xff08;进程名后面带d的基本就是守护进程&#xff09; 长期运行&#xff08;一般是开机运行直到关机时关闭&…

【Node.js从基础到高级运用】二十五、Node.js中Cluster的作用

引言 Node.js中的cluster模块允许您轻松创建共享服务器端口的子进程。这是一个核心模块&#xff0c;用于在Node.js应用程序中实现多进程架构&#xff0c;以充分利用多核CPU系统的计算能力。 cluster介绍 当您启动一个Node.js应用程序时&#xff0c;默认情况下它运行在单个进程…

【Python】什么是pip,conda,pycharm,jupyter notebook?conda基本教程

pip--conda--pycharm--jupyter notebook &#x1f343;pip&#x1f343;conda&#x1f343;Pycharm&#x1f343;jupyter notebook&#x1f343;Conda基本教程☘️进入base环境☘️创建一个新的环境☘️激活环境☘️退出环境☘️查看电脑上都安装了哪些环境☘️删除已创建的项目…