还记得第一次见该题根本无从下手。其实,我们不妨把问题拆解,简单化。不要怕自己写的是暴力算法,有很多算法技巧其实就是在暴力算法的基础上优化得来。

题目目的是求所有可接雨水数量,我们可以求出每一个位置可接雨水数量,最后加起来即可。

就是如下流程:

int trap(vector<int>& height) {int n = height.size();vector<int> water(n, -1);for(int i = 0; i < n; ++i){// 求height[i]能存多少水water[i] = getWater(height, i);}int ans = 0;for(int x : water){ans += x;}return ans;}

那么现在问题只有一个,如何求单个位置的可接雨水量,根据题目,不难想到,只需要找左右两边可以“望”到的最高值,选取二者最小值,减去该位置高度即可。

完整代码:

class Solution {
public:int trap(vector<int>& height) {int n = height.size();vector<int> water(n, -1);for(int i = 0; i < n; ++i){// 求height[i]能存多少水water[i] = getWater(height, i);}int ans = 0;for(int x : water){ans += x;}return ans;}int getWater(vector<int>& height, int k){int n = height.size();// 计算左高点int lmax = height[k];for(int i = k - 1; i >= 0; --i){if(height[i] > lmax){lmax = height[i];}}// 计算右高点int rmax = height[k];for(int i = k + 1; i < n; ++i){if(height[i] > rmax){rmax = height[i];}}// 返回结果return min(lmax, rmax) - height[k];}
};

不过这肯定是超时的。

在此基础上,分析算法中重复计算的部分,我们在每一个位置得到 lmax 和 rmax 时都从零开始计算,这样很浪费算力。由于求 lmaxrmax 本质就是简单的求单调最大值,所以我们可以一遍遍历求出每个位置的 lmax 或 rmax ,因为我们只需要向对应方向“望”到的最大值即可。

class Solution {
public:int trap(vector<int>& height) {int n = height.size();vector<int> lmax(n, 0);vector<int> rmax(n, 0);lmax[0] = height[0];for(int i = 1; i < n; ++i){lmax[i] = max(lmax[i - 1], height[i]);}rmax[n - 1] = height[n - 1];for(int i = n - 2; i >= 0; --i){rmax[i] = max(rmax[i + 1], height[i]);}int ans = 0;for(int i = 0; i < n; i++){ans += min(lmax[i], rmax[i]) - height[i];}return ans;}
};

最后,考虑是否可以继续优化时间和空间。

我们假设只有两个变量,分别记录 1 位置的 lmaxn - 2 位置的 rmax ,考虑现在谁的雨水量是可求的。

思考分析后得出,当两个变量进行比较,较小的一方所指位置的雨水量是可求的。

lmax 指向 1 位置,值为100rmax 指向 n - 2 为位置,值为70为例,即使当前 lmax 对于      n - 2位置来说并不是真正的 lmax ,但其真正值只会比100大,而接雨水量是由小的一方决定的。

class Solution {
public:int trap(vector<int>& height) {int lidx = 1;int lmax = height[0];int ridx = height.size() - 2;int rmax = height[ridx + 1];int ans = 0;while(lidx <= ridx){if(lmax > rmax){ans += max(0, rmax - height[ridx]);rmax = max(rmax, height[ridx--]);}else{ans += max(0, lmax - height[lidx]);lmax = max(lmax, height[lidx++]);}}return ans;}
};

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

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

相关文章

Go 语言-->指针

Go 语言–>指针 它允许你操作内存中的实际数据&#xff0c;而不仅仅是数据的副本。指针存储的是另一个变量的内存地址&#xff0c;而不是变量的实际值。 1. 什么是指针 指针是存储变量内存地址的变量&#xff0c;它指向另一个变量。通过指针&#xff0c;你可以间接地访问和修…

软工八将:软件开发全流程核心角色体系解析

软工八将&#xff1a;软件开发全流程核心角色体系解析 作者注&#xff1a;本概念是由大学生董翔提出&#xff0c;具有一些影响意义。 在现代软件开发领域&#xff0c;团队角色的专业化分工是产品成功的核心保障。“软工八将”作为一套系统梳理软件开发全流程核心角色的术语&…

安全风险监测系统是什么?内容有哪些?

安全风险监测系统是基于物联网感知网络与智能分析技术的综合管理平台&#xff0c;通过实时采集、分析和评估各类安全风险指标&#xff0c;构建起覆盖识别、预警、处置全流程的主动防御体系。作为现代安全管理的中枢神经系统&#xff0c;该系统实现了从被动响应到主动预防的范式…

车载诊断架构 ---面向售后的DTC应该怎么样填写?

我是穿拖鞋的汉子,魔都中坚持长期主义的汽车电子工程师。 老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 简单,单纯,喜欢独处,独来独往,不易合同频过着接地气的生活,除了生存温饱问题之外,没有什么过多的欲望,表面看起来很高冷,内心热情,如果你身…

墨者:SQL注入漏洞测试(宽字节)

墨者学院&#xff1a;SQL注入漏洞测试(宽字节)&#x1f680; 1. 宽字节注入原理✨ 1.1. 与普通注入对比⭐ 特性普通注入宽字节注入适用场景无转义处理使用addslashes()等转义函数核心原理直接闭合引号利用GBK等编码吞掉转义符\关键字符 " -- #%df %5c防御难度易防御需调…

(二)Eshop(RabbitMQ手动)

文章目录项目地址一、Rabbit MQ1.1 Pulibsher1. IRabbitMQPublisher接口2. RabbitMQPublisher接口实现3. 使用1.2 Consumer1. 消费接口2. 实现消费者接口项目地址 教程作者&#xff1a;教程地址&#xff1a; 代码仓库地址&#xff1a; 所用到的框架和插件&#xff1a; dbt a…

WPF高级学习(一)

文章目录一、理解进程和线程1. 进程&#xff1a;就像一个独立的“工厂”举例&#xff1a;2. 线程&#xff1a;就像工厂里的“工人”举例&#xff1a;总结&#xff1a;进程 vs 线程二、线程一、WPF 中的线程类型二、核心规则&#xff1a;线程亲和性&#xff08;Thread Affinity&…

JAVA知识点(四):SpringBoot与分布式、微服务架构

文章目录SpringBoot 使用 Validation 进行参数校验并统一返回校验异常引入相应的依赖Validation的基本校验注解添加参数校验在DTO的属性上添加校验在controller对应的DTO添加Valid或者Validated对于复杂String校验我们可以使用正则来校验&#xff0c;如下所示&#xff1a;自定义…

GPU 服务器ecc报错处理

1. 常见原因分析内存硬件问题&#xff1a;DIMM 内存模块损坏或接触不良&#xff08;最常见原因&#xff09;。内存插槽氧化、松动或物理损坏。内存与主板兼容性问题&#xff08;尤其是非原厂内存&#xff09;。环境因素&#xff1a;服务器内部温度过高&#xff0c;导致内存稳定…

STM32入门之通用定时器PWM

一、通用定时器简介STM32通用定时器由一个通过可编程预分频器驱动的16位自动重装载计数器组成&#xff0c;适用于多种应用场景&#xff0c;包括测量输入信号的脉冲长度&#xff08;利用输入捕获功能&#xff09;和生成输出波形&#xff08;使用输出比较及PWM功能&#xff09;。…

第十八节 MATLAB for循环

MATLAB中 for 循环是一个重复的控制结构&#xff0c;可以有效地写一个循环&#xff0c;只是执行的次数是特定的。MATLAB for 循环语法:MATLAB中的 for循环的语法如下&#xff1a;for index values<program statements>... endfor 循环的值有下述三种形式之一&#xff1a…

嵌入式硬件篇---zigbee无线串口通信问题解决方法

针对 ZigBee 无线串口通信中接收异常的问题&#xff0c;需结合其射频特性、网络机制、硬件配置等多维度原因&#xff0c;采取针对性解决措施。以下从具体场景出发&#xff0c;提供可落地的解决方法&#xff1a;一、解决射频层干扰与信号衰减问题射频层是无线通信的基础&#xf…

移动高清盒子6PRO-河南创维E900V22D-晶晨S905L3B-4+16G-安卓9-线刷固件包

移动高清盒子6PRO-河南创维E900V22D-晶晨S905L3B-416G-安卓9-线刷固件包线刷方法&#xff1a;1、准备好一根双公头USB线刷刷机线&#xff0c;长度30-50CM长度最佳&#xff0c;同时准备一台电脑&#xff1b;2、电脑上安装好刷机工具Amlogic USB Burning Tool 软件 →打开软件 →…

台式电脑有多个风扇开机只有部分转动的原因

一、风扇未连接或连接松动这是最常见的原因之一&#xff0c;台式机风扇通常需要通过线材与主板或电源连接&#xff1a;主板接口问题&#xff1a;CPU 风扇、机箱风扇等多连接到主板的风扇接口&#xff08;如 CPU_FAN、SYS_FAN&#xff09;&#xff0c;若线材未插紧、插错接口&am…

【测试报告】思绪网(Java+Selenium+Jmeter自动化测试)

一、项目简介思绪网作为一种在线交流平台&#xff0c;支持用户在平台下发布文章&#xff0c;并进行讨论。主要由登录页面&#xff0c;论坛页面&#xff0c;帖子编辑页&#xff0c;帖子详情页等页面组成。二、项目功能1.登录页面&#xff1a;输入正确的账号密码进行登录,跳转博客…

Nestjs框架: 基于Mongodb的多租户功能集成和优化

概述 基于前文&#xff0c;我们知道如何集成多租户的相关功能了, 现在我们继续集成Monodb的多租户形式需要注意的是&#xff0c;MongoDB 在 NestJS 中的使用过程中存在一些“坑点”如果按照默认方式集成&#xff0c;会发现连接数在不断增长&#xff0c;即使我们请求的是相同的数…

如何利用机器学习分析筛选生物标记物

在生物信息学中&#xff0c;Lasso回归、随机森林&#xff08;Random Forest&#xff09;和XGBoost因其各自的特性和优势&#xff0c;被广泛应用于基因组学、蛋白质组学、药物发现和疾病机制研究等领域。 Lasso回归 癌症亚型分类&#xff1a;从TCGA数据中筛选驱动基因&#xf…

计算机网络(基础篇)

TCP/IP 网络模型 应用层&#xff08;Application Layer&#xff09; 应用层只需要专注于为用户提供应用功能&#xff0c;比如 HTTP、FTP、Telnet、DNS、SMTP等。应用层是工作在操作系统中的用户态&#xff0c;传输层及以下则工作在内核态。传输层&#xff08;Transport Layer&a…

全面解析 CSS Flex 布局:从入门到精通的所有属性详解

1. Flex 容器属性 通过 display: flex 或 display: inline-flex 将元素设置为 Flex 容器。以下是所有容器属性。 1.1 display: flex | inline-flex 作用&#xff1a;定义一个 Flex 容器。可选值&#xff1a; flex&#xff1a;块级容器&#xff0c;占据整行。inline-flex&#x…

数据结构:对角矩阵(Diagonal Matrix)

目录 矩阵的传统表示&#xff1a;二维数组 &#x1f50d; 真正有用的数据是哪些&#xff1f; 从二维数组转为一维数组 用 C 类实现对角矩阵 1. 对角矩阵真正需要存什么&#xff1f; 2. 对角矩阵允许哪些行为&#xff1f; 3. 为什么要动态分配数组&#xff1f; 接下来推…