算法题 — 接雨水

给定 n 给非负整数,表示每个宽度为 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 个单位雨水(蓝色部分表示雨水)。

就是用一个数组表示一个条形图,问这个条形图最多能接多少水。

1 暴力解法

具体来讲,对于位置 i 能装下多少水呢?

数组

能装下 2 格。为什么呢?因为位置 i 处能达到的水柱的高度和其左边的最高柱子、右边的最高柱子有关。其左边最高柱子的高度是 2,其右边最高柱子的高度是 3,因为 height[i] 的高度是 0,所以位置 i 处能装下 2 格的水。

这里我们假设左右两个最高柱子的高度分别为 leftMax 和 rightMax,位置 i 处的水柱高度就是 min(leftMax, rightMax) - height[i]。

根据以上的思路:

fun trap(height: Array<Int>): Int {val n = height.sizevar res = 0// 位置 0 和位置 n - 1 处无法存储水for (i in 1 until n - 1) {var leftMax = 0 // 位置 i 处左边最高的柱子var rightMax = 0 // 位置 i 处右边最高的柱子// 寻找左边最高的柱子,这里到 i 是因为后面要 -height[i]for (j in 0..i) {leftMax = leftMax.coerceAtLeast(height[j])}// 寻找右边最高的柱子,这里从 i 开始是因为后面要 -height[i]for (j in i until n - 1) {rightMax = rightMax.coerceAtLeast(height[j])}res += leftMax.coerceAtMost(rightMax) - height[i]}return res
}
2 备忘录优化

在暴力算法中,需要计算每个位置的 leftMax 和 rightMax,我们可以直接先把结果计算出来,不需要每次都遍历。

定义两个数组 leftMax 和 rightMax 充当备忘录,leftMax[i] 表示位置 i 左边最高的柱子高度,rightMax[i] 表示位置 i 右边最高的柱子高度。预先把这两个数组准备好,避免重复计算:

fun trap(height: Array<Int>): Int {val n = height.sizevar res = 0// 数组备忘录val leftMax = IntArray(n)val rightMax = IntArray(n)// 初始化leftMax[0] = height[0]rightMax[n - 1] = height[n - 1]for (i in 1 until n) {leftMax[i] = height[i].coerceAtLeast(leftMax[i - 1])}for (i in n - 2 downTo 0) {rightMax[i] = height[i].coerceAtLeast(rightMax[i + 1])}for (i in 1 until n - 1) {res += leftMax[i].coerceAtMost(rightMax[i]) - height[i]}return res
}

备忘录算法和暴力算法的思路差不多,就是避免了重复计算。

4 双指针解法
fun trap(height: Array<Int>): Int {val n = height.sizevar res = 0var left = 0var right = n - 1// 左边最高柱子的高度和右边最高柱子的高度var leftMax = height[0]var rightMax = height[n - 1]while (left < right) {leftMax = leftMax.coerceAtLeast(height[left])rightMax = rightMax.coerceAtLeast(height[right])if (leftMax < rightMax) { // 左边的柱子低于右边柱子的高度,水的高度只和较低的柱子有关res += leftMax - height[left]left++} else { // 右边的柱子低于左边柱子的高度,水的高度只和较低的柱子有关res += rightMax - height[right]right--}}return res
}

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

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

相关文章

布尔运算00

题目链接 布尔运算 题目描述 注意点 运算符的数量不超过 19 个布尔表达式由 0 (false)、1 (true)、& (AND)、 | (OR) 和 ^ (XOR) 符号组成算出有几种可使该表达式得出 result 值的括号方法 解答思路 可以使用动态规划根据左右两侧区间不同结果相应组合数量计算得出当前…

国产Cortex-A55人工智能教学实验箱_基于Python机械臂跳舞实验案例分享

一、实验目的 本实验通过TL3568-PlusTEB教学实验箱修改机械臂不同舵机的角度&#xff0c;增加延迟时间&#xff0c;从而做到机械臂跳舞的效果。 二、实验原理 ROS&#xff08;机器人操作系统&#xff09; ROS&#xff08;机器人操作系统&#xff09;&#xff0c;是专为机器人…

Golang解决bufio.Scanner: token too long的问题

Golang解决bufio.Scanner: token too long的问题 在Go语言中使用bufio.Scanner时&#xff0c;遇到“token too long”&#xff08;标记过长&#xff09;的错误&#xff0c;通常是因为尝试读取的行太大&#xff0c;超过了bufio.Scanner默认的最大容量。bufio.Scanner默认的缓冲…

@ComponentScan注解在Spring的作用

ComponentScan注解的作用是什么&#xff1f; 告知Spring扫描那些包下的类&#xff0c;可以配置includeFilters&#xff0c;excludeFilters&#xff0c;过滤某些类&#xff0c;更多内容可以具体看下此注解文件。 Spring是如何通过这个注解将类注入到Ioc容器中的&#xff1f; 请…

[linux]sed命令基础入门详解

sed是一种流编辑器&#xff0c;它一次处理一行内容。处理时&#xff0c;把当前处理的行存储在临时缓冲区中&#xff0c;称为“模式空间”&#xff0c;接着用sed命令处理缓冲区中的内容&#xff0c;处理完成后&#xff0c;把缓冲区的内容送往屏幕。接着处理下一行&#xff0c;这…

生命在于折腾——Macbook虚拟机开启360核晶

首先启动PD虚拟机&#xff0c;打开360&#xff0c;发现提示如下&#xff1a; 此时将虚拟机关机。 打开该虚拟机设置&#xff1a; 将虚拟机监控程序改为Parallels&#xff0c;并启动nested虚拟化。 改好后截图如下&#xff1a; 保存设置&#xff0c;开机 此时就可以开启了…

硬件实用技巧:摄像头常用的输出协议类型和输出接口类型

若该文为原创文章&#xff0c;转载请注明原文出处 本文章博客地址&#xff1a;https://hpzwl.blog.csdn.net/article/details/140042485 长沙红胖子Qt&#xff08;长沙创微智科&#xff09;博文大全&#xff1a;开发技术集合&#xff08;包含Qt实用技术、树莓派、三维、OpenCV…

docker 多网卡指定网卡出网

前言 宿主机中有多个网卡 ens160 192.168.4.23/20 内网通信用 ens192 10.31.116.128/24 出公网访问-1 ens193 10.31.116.128/24 出公网访问-2 现在需要不同容器中不同出网访问&#xff0c;举例 容器1 192.168.0.1/20 网段走宿主机 ens160网卡&#xff0c;否则全部走ens192 网…

Java中的事件驱动编程模型

Java中的事件驱动编程模型 大家好&#xff0c;我是免费搭建查券返利机器人省钱赚佣金就用微赚淘客系统3.0的小编&#xff0c;也是冬天不穿秋裤&#xff0c;天冷也要风度的程序猿&#xff01;今天我将为大家介绍Java中的事件驱动编程模型。事件驱动编程模型是一种以事件为核心驱…

太速科技-FMC144 -八路 250MSPS 14bit AD FMC子卡

FMC144 -八路 250MSPS 14bit AD FMC子卡 一、板卡概述   FMC144是一款具有8通道模数转换器&#xff08;ADC&#xff09;的FMC卡&#xff0c;具有14bit分辨率&#xff0c;最大采样速率达250Msps。时钟配置芯片为AD9516-1&#xff0c;可由板载10MHz时钟提供参考&#xff0c;也可…

STM32人体心电采集系统

资料下载地址&#xff1a;STM32人体心电采集系统 1、项目功能介绍 此项目主要实现了以STM32为核心的人体心电采集系统软硬件的设计。软件设计过程是在STM32上移植的uCGUI做图形界面&#xff0c;并如实显示采集到的心电波形信号&#xff0c;有SD卡存储和USB数据传输功能。 2、实…

GEOS学习笔记(二)

Point类型GEOS_POINT 创建方法&#xff1a; //从字符串创建 GEOSGeometry* p GEOSGeomFromWKT("POINT(10 10)"); //从坐标创建 GEOSGeometry* p GEOSGeom_createPointFromXY(-100,0); //从GEOSCoordSequence创建 double point[] {100.0,0.0}; GEOSCoordS…

Ubuntu20.04安装Prometheus监控系统

环境准备&#xff1a; 服务器名称内网IP公网IPPrometheus服务器192.168.0.23047.119.21.167Grafana服务器192.168.0.23147.119.22.8被监控服务器192.168.0.23247.119.22.82 更改主机名方便辨认 hostnamectl set-hostname prometheus hostnamectl set-hostname grafana hostn…

SAS:quote函数合dhms函数

quote函数 dhms函数 中间停药时的给药日期确定

stm32 No traget connected/debug识别不到串口的问题

关于stm32串口识别不到&#xff0c;第一步先确定是否线接错&#xff08;stlink与stm32接口对应&#xff09;&#xff0c;如果确认接线没有问题的话&#xff0c;可以使用以下方法&#xff0c;成功率较高。 首先将stlink的boot0置1&#xff0c;就是把跳线帽换到高电平这一侧&…

php+极光推送(厂商通道) jpush推送

php极光推送&#xff08;厂商通道&#xff09; jpush推送 此方法可放到common.php内调用 if (!function_exists("push")) {/*** Notes:* User: 任性不起来了* Date: 2024/6/28 16:44* param $accept_id 用户ID* param $message 消息内容* param int $orderrecordin…

投标书制作

一、投标书的基本要求l . 帮助与你的标书读者沟通。从这个角度上来讲&#xff0c;标书是一篇针对用户需求的论文&#xff0c;逻辑结构和语言一定要清晰、可读。考虑到评标专家一般都具有较好的学术经验&#xff0c;其中很多还是教授、博导&#xff0c;投标的语言要针对读者的阅…

机器学习之子监督学习方法BYOL(Bootstrap Your Own Latent)

BYOL(Bootstrap Your Own Latent)是一种自监督学习方法,由DeepMind于2020年提出。它是一种通过自我引导来学习特征表示的算法,不需要对比学习(contrastive learning)中的负样本对,而是通过自身的表示进行学习。 BYOL的基本概念 自监督学习: 自监督学习是一种无需人工标…

国产固态光耦在工业照明领域的应用

工业照明作为工厂和生产设施中不可或缺的一部分&#xff0c;其效率和安全性直接影响到生产运行的顺畅性和员工的工作环境。国产固态光耦作为现代工业照明技术的重要组成部分&#xff0c;在提升照明系统效率和安全性方面发挥着关键作用。本文将深入探讨国产固态光耦在工业照明领…

【高级篇】MySQL与云环境(十七)

引言 随着云计算技术的飞速发展,MySQL在云环境中的应用日益广泛。本章我们将深入探讨如何在云平台如Amazon Web Services (AWS)的RDS、Google Cloud SQL以及Microsoft Azure的Database for MySQL中部署、迁移、管理MySQL数据库,并针对云环境中可能遇到的挑战提出诊断与解决策…