力扣(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.hqwc.cn/news/630542.html

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

相关文章

二刷大数据(三)- Flink1.17

目录 Flink概念与SparkStreaming区别分层API 工作流程部署模式**Local Mode****Standalone Mode****YARN Mode****Kubernetes Mode****Application Mode** 运行架构stand alone 核心概念算子链任务槽 窗口窗口**窗口的目的与作用****时间窗口&#xff08;Time Windows&#xff…

jenkins 部署 vue 项目

jenkins 部署 vue 项目 环境 系统&#xff1a;CentOS7.9 Jenkins&#xff1a;最新LTS版本 nginx: 1.24.x gitLab: 打包机&#xff1a;jenkins所在服务器 目标机器&#xff1a;nginx所在服务器 jenkins部署配置 关键脚本 #node -v #已经安装node_module就无需执行install安…

配置静态路由实现全网互通

1、实验环境 如图下所示&#xff0c;三台路由器R1&#xff0e;R2&#xff0c;R3两两互连&#xff0c;每台路由器上都配置了Loopback地址模拟网络环境。 2、需求描述 需要在三台路由器上配置静态路由&#xff0c;以实现各网段之间的互通。 若要实现全网互通,必须明确如下两个问…

Centos7.9 脚本一键部署nextcloud,配置Nginx代理Https。

目录 一键安装nextcloud 出现错误TypeError Cannot read properties of undefined (reading ‘writeText‘) 生成自签名SSL证书 编辑Nginx配置文件 启动Nginx 一键安装nextcloud 本脚本参考文章&#xff0c;本文较长建议先看完在操作&#xff01;&#xff01;&#xff01;…

Vue之v-on事件修饰符的含义及使用

背景&#xff1a;Vue 拆封了一个组件&#xff0c;在组件里面会使用一个方法来改变父组件传过来的值&#xff0c; 但是在子组件里面操作父组件的数据变更&#xff0c;实在比较麻烦&#xff08;因为单向数据流&#xff09;&#xff0c; So 能不能直接在组件上面绑定事件方法呢&…

HiveSql中的函数家族(二)

一、窗口函数 1、什么是窗口函数 在 SQL 中&#xff0c;窗口函数&#xff08;Window Functions&#xff09;是一种特殊的函数&#xff0c;它允许在查询结果集的特定窗口&#xff08;通常是一组行&#xff09;上执行聚合、分析和计算操作&#xff0c;而无需聚合整个结果集。窗口…

HTML重要标签梳理学习

1、HTML文件的框架 使用VS Code编码时&#xff0c;输入!选中第一个&#xff01;就可以快速生成一个HTML文件框架。 2、标签 <hr> <!--下划线--> <br> <!--换行--> <strong>加粗</strong> &…

【氮化镓】GaN HEMT失效物理和可靠性

概述: 本文是一篇关于AlGaN/GaN基高电子迁移率晶体管(HEMTs)的失效物理和可靠性研究的综述文章,发表在2013年10月的《IEEE Transactions on Electron Devices》上。文章由Enrico Zanoni等人撰写,主要关注了影响栅极边缘和肖特基结的失效机制,并探讨了提高这些器件可靠性…

SPI接口的74HC595驱动数码管实现

摸鱼记录 Day_17 (((^-^))) review 前边已经学习了&#xff1a; 数码管显示原理&#xff1a;数码管动态扫描显示-CSDN博客 且挖了个SPI的坑坑 1. 今日份摸鱼任务 学习循环移位寄存器18 串行移位寄存器原理详解_哔哩哔哩_bilibili 学习SPI接口的74HC595驱动数码管19 SPI…

JVM之垃圾回收机制

一、常量池的位置 方法区和永久代以及元空间是什么关系呢&#xff1f; 方法区和永久代以及元空间的关系很像 Java 中接口和类的关系&#xff0c;类实现了接口&#xff0c;这里的类就可以看作是永久代和元空间&#xff0c;接口可以看作是方法区&#xff0c;也就是说永久代以及元…

在mysql函数中启动事物和行锁/悲观锁实现并发条件下获得唯一流水号

业务场景 我有一个业务需求&#xff1a;我有一个报卡表 report里面有一个登记号字段 fcardno、地区代码 faddrno和发病年份 fyear&#xff0c;登记号由**“4位地区代码”“00”“发病年份”“5位流水号”**组成&#xff0c;我要在每次插入一张报卡&#xff08;每一行数据&#…

布局香港之零售中小企篇 | 传承之味,迈向数字化经营的时代

随着内地与香港两地经贸合作日渐紧密&#xff0c;越来越多内地消费品牌将目光投向香港这片充满机遇的热土&#xff0c;纷纷入驻香港市场。「北店南下」蔚然成风&#xff0c;其中不乏已在内地市场深耕多年的传统老字号。数字化经营时代&#xff0c;老字号焕新刻不容缓&#xff0…