【力扣】42. 接雨水 <模拟、双指针、单调栈>

【力扣】42. 接雨水

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

目录

    • 【力扣】42. 接雨水
    • 题解
        • 暴力
        • 双指针
        • 单调栈

示例 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 * 1 0 4 10^4 104
0 <= height[i] <= 1 0 5 10^5 105

题解

暴力

按照列来计算的话,宽度一定是1,把每一列的雨水的高度求出来即可。
每一列雨水的高度,取决于该列左侧最高的柱子和右侧最高的柱子中最矮的那个柱子的高度。
min(左边柱子的最高高度,记录右边柱子的最高高度) - 当前柱子高度
min(lHeight, rHeight) - height
在这里插入图片描述

public class Solution {public int trap(int[] height) {int sumWater = 0;for (int i = 0; i < height.length; i++) {// 第一个柱子和最后一个柱子不接雨水if (i==0 || i== height.length - 1) {continue;}// 记录右边柱子的最高高度int rHeight = height[i];// 记录左边柱子的最高高度int lHeight = height[i];// 求左边最高柱子for (int l = i-1; l >= 0; l--) {if(height[l] > lHeight) {lHeight = height[l];}}// 求右边最高柱子for (int r = i+1; r < height.length; r++) {if (height[r] > rHeight) {rHeight = height[r];}}//每一列雨水的高度,取决于,该列左侧最高的柱子和右侧最高的柱子中 最矮的那个柱子的高度。int h = Math.min(lHeight, rHeight) - height[i];if (h > 0) {sumWater += h;}}return sumWater;}
}

双指针

每到一个柱子都向两边遍历一遍,这其实是有重复计算的,为了得到两边的最高高度,使用了双指针来遍历。把每一个位置的左边最高高度记录在一个数组上(maxLeft),右边最高高度记录在一个数组上(maxRight),这样就避免了重复计算。

当前位置,左边的最高高度是前一个位置的左边最高高度和本高度的最大值。当前位置,右边的最高高度是前一个位置的右边最高高度和本高度的最大值。

public class Solution {public int trap(int[] height) {// 每到一个柱子都向两边遍历一遍,这其实是有重复计算// 把每一个位置的左边最高高度记录在一个数组上(maxLeft),右边最高高度记录在一个数组上(maxRight)int[] maxLeft = new int[height.length];int[] maxRight = new int[height.length];// 记录每个柱子左边柱子最大高度maxLeft[0] = height[0];for (int i = 1; i < height.length; i++) {//当前位置,左边的最高高度是前一个位置的左边最高高度和本高度的最大值maxLeft[i] = Math.max(height[i], maxLeft[i - 1]);}// 记录每个柱子右边柱子最大高度maxRight[height.length - 1] = height[height.length - 1];for (int i = height.length - 2; i >= 0; i--) {//当前位置,右边的最高高度是前一个位置的右边最高高度和本高度的最大值maxRight[i] = Math.max(height[i], maxRight[i + 1]);}// 求和int sumWater = 0;for (int i = 0; i < height.length; i++) {// 第一个柱子和最后一个柱子不接雨水if (i==0 || i== height.length - 1) {continue;}int h = Math.min(maxLeft[i], maxRight[i]) - height[i];if (h > 0) {sumWater += h;}}return sumWater;}
}

单调栈

单调栈是按照行方向来计算雨水。
栈头(元素从栈头弹出)到栈底的顺序应该是从小到大的顺序。因为一旦发现添加的柱子高度大于栈头元素了,此时就出现凹槽了,栈头元素就是凹槽底部的柱子,栈头第二个元素就是凹槽左边的柱子,而添加的元素就是凹槽右边的柱子。
遇到相同高度的柱子:要求宽度的时候 如果遇到相同高度的柱子,需要使用最右边的柱子来计算宽度。
在这里插入图片描述

import java.util.Stack;public class Solution {public int trap(int[] height){int sumWater = 0;if (height.length <= 2) {return 0;}Stack<Integer> stack = new Stack<>();stack.push(0);for (int index = 1; index < height.length; index++){//情况一if (height[index] < height[stack.peek()]){stack.push(index);}//情况二else if (height[index] == height[stack.peek()]){// 因为相等的相邻墙,左边一个是不可能存放雨水的,所以pop左边的index, push当前的indexstack.pop();stack.push(index);}//情况三else{while (!stack.isEmpty() && (height[index] > height[stack.peek()])){int mid = stack.peek();stack.pop();if (!stack.isEmpty()){int left = stack.peek();//长就是通过柱子的高度来计算int h = Math.min(height[left], height[index]) - height[mid];//宽是通过柱子之间的下标来计算int w = index - left - 1;int area = h * w;if (area > 0) {sumWater += area;}}}stack.push(index);}}return sumWater;}
}

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

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

相关文章

数据结构<树和二叉树>顺序表存储二叉树实现堆排

✨Blog&#xff1a;&#x1f970;不会敲代码的小张:)&#x1f970; &#x1f251;推荐专栏&#xff1a;C语言&#x1f92a;、Cpp&#x1f636;‍&#x1f32b;️、数据结构初阶&#x1f480; &#x1f4bd;座右铭&#xff1a;“記住&#xff0c;每一天都是一個新的開始&#x1…

c语言实现MD5算法

MD5加密 文章目录 MD5加密MD5介绍应用场景代码分析 &#xff08;基于qt5.14.2&#xff09;测试记录 MD5介绍 1。 一种单向加密算法&#xff0c;即对明文加密&#xff0c;而不能通过密文得到明文。对原数据的任何改动&#xff0c;哪怕是1字节&#xff0c;得到的MD5值都有很大的区…

vue路由及打包部署

vue路由&#xff08;前端路由&#xff09;&#xff1a;URL中的hash&#xff08;#号&#xff09;与组件之间的对应关系。 一、安装vue路由 npm install vue-router3.5.1 二、定义路由表 路由表主要记录hash&#xff08;#号&#xff09;与组件之间的对应关系。主要定义在route…

FPGA:uart原理+tx发送模块+rx接收模块

文章目录 一、串口通信二、UART通信三、tx发送模块四、rx模块接收 一、串口通信 处理器与外部设备通信的两种方式&#xff1a; 串行通信&#xff1a; 指数据的各个位使用多条数据线同时进行传输。 并行通信&#xff1a; 将数据分成一位一位的形式在一条数据线上逐个传输。 串…

SQL Injection

SQL Injection 就是通过把恶意的sql命令插入web表单递交给服务器&#xff0c;或者输入域名或页面请求的查询字符串递交到服务器&#xff0c;达到欺骗服务器&#xff0c;让服务器执行这些恶意的sql命令&#xff0c;从而让攻击者&#xff0c;可以绕过一些机制&#xff0c;达到直…

sql server安装报错 合成活动模板库(ATL) 失败

错误 “合成活动模板库(ATL) 规则失败“ 解决办法&#xff1a; 进入SQL Server 2008R2安装包目录找到文件&#xff1a;sqlsupport_msi&#xff0c;安装此文件之后&#xff0c;再安装SQL Server&#xff0c;便可解决该问题。C:\SQL Server 2008R2\new\SQL Server 2008R2\2052_CH…

Java虚拟机(JVM):虚拟机栈溢出

一、概念 Java虚拟机栈溢出&#xff08;Java Virtual Machine Stack Overflow&#xff09;是指在Java程序中&#xff0c;当线程调用的方法层级过深&#xff0c;导致栈空间溢出的情况。 Java虚拟机栈是每个线程私有的&#xff0c;用于存储方法的调用和局部变量的内存空间。每当…

如何学习专业的学术用语01

问题的提出——凭啥人家写的词汇这么专业 做法一 做法二&#xff1a;做一个专业数据库 专门做教育技术类的

Android Ble蓝牙App(六)请求MTU与显示设备信息

前言 在上一篇文章中已经了解了数据操作的方式&#xff0c;而数据交互的字节长度取决于我们手机与蓝牙设备的最大支持长度。 目录 Ble蓝牙App&#xff08;一&#xff09;扫描Ble蓝牙App&#xff08;二&#xff09;连接与发现服务Ble蓝牙App&#xff08;三&#xff09;特性和属…

unity 之 Vector 数据类型

文章目录 Vector 1Vector 2Vector 3Vector 4 Vector 1 在Unity中&#xff0c;Vector1 并不是一个常见的向量类型。 如果您需要表示标量&#xff08;单个值&#xff09;或者只需要一维的数据&#xff0c;通常会直接使用浮点数&#xff08;float&#xff09;或整数&#xff08;in…

Linux命令200例:tail用来显示文件的末尾内容(常用)

&#x1f3c6;作者简介&#xff0c;黑夜开发者&#xff0c;全栈领域新星创作者✌。CSDN专家博主&#xff0c;阿里云社区专家博主&#xff0c;2023年6月csdn上海赛道top4。 &#x1f3c6;数年电商行业从业经验&#xff0c;历任核心研发工程师&#xff0c;项目技术负责人。 &…

【ARM】Day4 点亮LED灯

1. 思维导图 2. 自己编写代码实现三盏灯点亮 .text .global _start _start: /**********LED1&#xff0c;LED2,LED3点灯:PE10,PF10,PE8**************/ RCC_INIT:使能GPIOE组/GPIOF组控制器,通过RXCC_MP_AHB4ENSETR设置第[5:4]位写1,地址:0x50000A28[5:4]1ldr r0,0x50000A28 …

【深入探究人工智能】:常见机器学习算法总结

文章目录 1、前言1.1 机器学习算法的两步骤1.2 机器学习算法分类 2、逻辑回归算法2.1 逻辑函数2.2 逻辑回归可以用于多类分类2.3 逻辑回归中的系数 3、线性回归算法3.1 线性回归的假设3.2 确定线性回归模型的拟合优度3.3线性回归中的异常值处理 4、支持向量机&#xff08;SVM&a…

〔012〕Stable Diffusion 之 中文提示词自动翻译插件 篇

✨ 目录 🎈 翻译插件🎈 下载谷歌翻译🎈 谷歌翻译使用方法🎈 谷歌翻译使用效果🎈 翻译插件 在插件列表中搜索 Prompt Translator可以看到有2个插件选项:一个是基于谷歌翻译 〔推荐〕、一个基于百度和deepl翻译推荐使用谷歌翻译,因为是离线翻译,所以使用时不用在乎是…

Java之SpringCloud Alibaba【四】【微服务 Sentinel服务熔断】

Java之SpringCloud Alibaba【四】【微服务 Sentinel服务熔断】 一、分布式系统遇到的问题1、服务挂掉的一些原因 二、解决方案三、Sentinel&#xff1a;分布式系统的流量防卫兵1、Sentinel是什么2、Sentinel和Hystrix对比3、Sentinel快速开发4、通过注解的方式来控流5、启动Sen…

vue3 基础知识

vue3创建一个项目 PS D:\code> npm init vuelatestVue.js - The Progressive JavaScript Framework√ Add TypeScript? ... No / Yes √ Add JSX Support? ... No / Yes √ Add Vue Router for Single Page Application development? ... No / Yes √ Add Pinia for sta…

电商项目part04 微服务拆分

微服务架构拆分 微服务介绍 英文:https://martinfowler.com/articles/microservices.html 中文:http://blog.cuicc.com/blog/2015/07/22/microservices 微服务拆分时机 如下场景是否需要进行微服务拆分&#xff1f; 代码维护困难&#xff0c;几百人同时开发一个模块&…

小白的Node.js学习笔记大全---不定期更新

Node.js是什么 Node. js 是一个基于 Chrome v8 引擎的服务器端 JavaScript 运行环境Node. js 是一个事件驱动、非阻塞式I/O 的模型&#xff0c;轻量而又高效Node. js 的包管理器 npm 是全球最大的开源库生态系统 特性 单一线程 Node.js 沿用了 JavaScript 单一线程的执行特…

【数据结构】链表的回文结构

文章目录 &#x1f30f;引言&#x1f9ed;[链表的回文结构](https://www.nowcoder.com/practice/d281619e4b3e4a60a2cc66ea32855bfa?tpId49&&tqId29370&rp1&ru/activity/oj&qru/ta/2016test/question-ranking)&#x1f6a9;&#x1f6a9;题目描述&#xf…

简单认识Docker数据管理

文章目录 为何需要docker数据管理数据管理类型 一、数据卷二、数据卷容器三、容器互联 为何需要docker数据管理 因为数据写入后如果停止了容器&#xff0c;再开启数据就会消失&#xff0c;使用数据管理的数据卷挂载&#xff0c;实现了数据的持久化&#xff0c;重启数据还会存在…