LeetCode题练习与总结:接雨水

一、题目

给定 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 * 104
  • 0 <= height[i] <= 105

二、解题思路

这个问题可以通过双指针或者暴力解法来解决。我们的目标是计算在每个低洼地带能够存储的雨水量。雨水的存储量取决于它两侧的最高柱子和当前柱子的高度。以下是解决这个问题的步骤:

  1. 遍历数组,找到两侧的最高柱子(可以使用双指针,一个从左边开始向右移动,另一个从右边向左移动)。
  2. 对于每个位置,其能够存储的雨水量取决于它两侧最高柱子中较低的一个和当前位置的柱子高度。
  3. 将每个位置能够存储的雨水量累加起来,即为最终的雨水总量。

三、具体代码

class Solution {
    public int trap(int[] height) {
        if (height == null || height.length == 0) {
            return 0;
        }

        int n = height.length;
        int leftMax[] = new int[n];
        int rightMax[] = new int[n];
        int trappedWater = 0;

        // 初始化左右两侧的最大高度数组
        leftMax[0] = height[0];
        for (int i = 1; i < n; i++) {
            leftMax[i] = Math.max(leftMax[i - 1], height[i]);
        }

        rightMax[n - 1] = height[n - 1];
        for (int i = n - 2; i >= 0; i--) {
            rightMax[i] = Math.max(rightMax[i + 1], height[i]);
        }

        // 计算每个位置的雨水量并累加
        for (int i = 0; i < n; i++) {
            trappedWater += Math.min(leftMax[i], rightMax[i]) - height[i];
        }

        return trappedWater;
    }
}

四、时间复杂度和空间复杂度

1. 时间复杂度
  • 初始化leftMax数组需要一次遍历,时间复杂度为O(n)。
  • 初始化rightMax数组需要一次遍历,时间复杂度为O(n)。
  • 计算每个位置的雨水量并累加的过程也是一次遍历,时间复杂度为O(n)。
  • 因此,总的时间复杂度是这三个步骤时间复杂度的和,即O(n) + O(n) + O(n) = O(n)。
2. 空间复杂度
  • leftMax数组和rightMax数组各占用O(n)的空间。
  • trappedWater变量占用常数空间。
  • 所以,总的空间复杂度是O(n),因为两个数组的空间占用是主要的。

五、总结知识点

  • 数组处理:代码处理了一个整数数组height,这个数组代表了每个柱子的高度。数组是编程中常用的数据结构,用于存储一系列元素。

  • 边界检查:在进行数组操作之前,代码首先检查了数组是否为空或者长度为0,这是为了避免在数组操作中出现NullPointerException或数组越界的错误。

  • 双指针/双端扫描:代码使用了两个数组leftMaxrightMax来分别从左到右和从右到左记录已访问过的最高柱子高度。这种从两端向中间扫描的方法是一种常见的双指针技巧。

  • 最大值更新:在填充leftMaxrightMax数组时,代码使用了Math.max函数来更新和记录每一步遇到的最大值。这是处理此类问题的关键步骤,需要知道如何更新和维护局部最大值。

  • 条件运算:在计算雨水量时,使用了Math.min函数来确定每个位置的雨水量,这是因为雨水量受到两侧最高柱子中较低的一个限制。

  • 累加求和:通过遍历数组并累加每个位置的雨水量,得到了总的雨水量。这是简单的循环和累加操作,是编程基础中常见的求和方法。

以上就是解决这个问题的详细步骤,希望能够为各位提供启发和帮助。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【MySQL】3.1MySQL索引的介绍

目录 一、索引的概念 数据库索引 索引的作用 索引的副作用 索引创建的原则&#xff08;应用场景&#xff09; 适合建立索引 二、索引的分类和创建 1.普通索引 创建普通索引 1.1直接创建 1.2修改表结构的方式创建普通索引 1.3创建表时创建普通索引 2.唯一索引 2.1…

如何在Android设备上运行深度网络

返回&#xff1a;OpenCV系列文章目录&#xff08;持续更新中......&#xff09; 上一篇&#xff1a; 下一篇&#xff1a; 介绍 在本教程中&#xff0c;您将了解如何使用 OpenCV 深度学习模块在 Android 设备上运行深度学习网络。教程是为 Android Studio 2022.2.1 编写的。…

实时数仓之实时数仓架构(Doris)

目前比较流行的实时数仓架构有两类,其中一类是以Flink+Doris为核心的实时数仓架构方案;另一类是以湖仓一体架构为核心的实时数仓架构方案。本文针对Flink+Doris架构进行介绍,这套架构的特点是组件涉及相对较少,架构简单,实时性更高,且易于Lambda架构实现,Doris本身可以支…

c++编写菱形图和计算100~200之间的素数

c编写菱形图 #include <stdio.h> int main() {int i,j,k,n;printf("请输入n:\n");scanf("%d",&n);for(i1;i<n;i){for(k1;k<n-i;k)printf(" ");for(j1;j<2*i-1;j)printf("*");printf("\n");}for(i1;i<…

【Charles如何对手机APP进行抓包和弱网测试】

一、Charles对APP抓包 1、前提条件&#xff1a; 1&#xff09;电脑上必须安装Charles工具&#xff0c;如没有安装可参考&#xff1a;【Charles抓包工具下载安装详细操作步骤】-CSDN博客 2&#xff09;手机和电脑必须在同一个局域网内&#xff08;连接同一个WiFi&#xff09;…

【java多线程】线程基础知识笔记

目录 1、多线程介绍 2、线程 3、线程的调度 4、线程的生命周期 5、线程的并行与并发 6、程的同步与异步 1、多线程介绍 多线程&#xff1a;指的是这个程序&#xff08;一个进程&#xff09;运行时产生了不止一个线程&#xff0c;是Java语言的重要特性&#xff0c;大量应用于…

[Linux开发工具]——gcc/g++的使用

Linux编译器——gcc/g的使用 一、快速认识gcc/g二、程序的翻译过程2.1 预处理&#xff08;.i文件&#xff09;2.2 编译&#xff08;.s文件&#xff09;2.3 汇编&#xff08;.o文件&#xff09;2.4 链接&#xff08;生成可执行文件或库文件&#xff09; 三、认识函数库3.1 静态库…

一大波新型勒索病毒来袭(更新)

目前勒索病毒仍然是全球最大的威胁&#xff0c;最近一年针对企业的勒索病毒攻击越来越多&#xff0c;大部分勒索病毒是无法解密的&#xff0c;一定要保持高度的重视&#xff0c;近期又有一大波新型勒索病毒来袭...... HildaCrypt勒索病毒 加密后的文件后缀名HCY&#xff0c;如…

qt 置顶窗口崩溃无法退出解决,停止运行快捷键设置

有时置顶窗口调试崩溃需要快捷键进行关闭&#xff0c;如下设置即可 这样就可以通过全局快捷键退出了&#xff0c;避免置顶崩溃无法关闭程序的问题。

《系统架构设计师教程(第2版)》第7章-系统架构设计基础知识-02-基于架构的软件开发方法

文章目录 1. 基于架构的软件设计&#xff08;ABSD&#xff09;1.1 概述1.2 ABSD方法的3个基础 2. 概念与术语2.1 设计元素2.2 视角与视图2.3 用例和质量场景 3. ABSD模型4. 体系结构需求4.1 需求获取4.2 标识构件4.3 架构需求评审 5. 体系结构设计5.1 体系结构设计5.2 软件体系…

8 克隆虚拟机

后期集群我们需要使用多台服务器&#xff0c;此处我们先克隆三台&#xff0c;master,slave01,slave02. 1.先关闭模版虚拟机。再选择 模版虚拟机hadoop100右击--》管理 --》克隆 2.下图中特别注意&#xff1a;建议使用集群的名字作为虚拟机名称。目前克隆主机master. 以上步骤完…

Django数据库查询

聚合查询 分组查询 F与Q查询 默认情况下,用Q包裹的两个条件,用逗号分割也是and关系 choices参数 只要某个字段的可能性是完全可以列举出来的,可以采取choices参数 该gender字段存的还是数字,但是如果数字在上面的元组列举范围内,该怎么获取对应的值,如果不在范围内,会怎…

Java学习笔记(20)

可变参数 输入的参数数量不确定 底层就是把输入的参数放进一个数组里 只能写一个可变参数如果还有其他形参&#xff0c;可变参数要放在最后写 可变参数在底层就是一个数组 Collections Addall shuffle 练习 package exercise;import java.util.ArrayList; import java.util.C…

Nacos详解,从安装到服务部署,及nginx反向代理

Nacos 安装 Windows安装 下载 在Nacos的GitHub页面&#xff0c;提供有下载链接&#xff0c;可以下载编译好的Nacos服务端或者源代码&#xff1a; GitHub主页&#xff1a;https://github.com/alibaba/nacos GitHub的Release下载页&#xff1a;https://github.com/alibaba/nacos…

更新数据库表中的数据

目录 update 加上各种限制条件 update update 表名set 列名1xx,列名2xx 指定更新某列数据如果不添加where子句,则为全列更新 也可以在原有基础上更新: 注意,mysql语法里不支持,必须是列名列名数值 加上各种限制条件 比如加上order by子句,where子句,limit等 这些条件对于up…

Flutter 运行 flutter doctor 命令长时间未响应

由于 Flutter 运行 flutter doctor 命令&#xff0c;会从 pub(https://pub.dev/ 类似于 Node.js 的 npm) 上进行资源的下载&#xff0c;如果没有配置国内镜像&#xff0c;可能会由于其服务器在国外导致资源下载慢或者下载不下来&#xff0c;所以出现了运行 flutter doctor 命令…

权限提升-Web权限提升篇划分获取资产服务后台系统数据库管理相互转移

知识点 1、权限提升转移-分类&高低&场景 2、Web权限提升及转移-后台&数据库 3、后台权限及转移-转移对象&后台分类 章节点&#xff1a; 1、Web权限提升及转移 2、系统权限提升及转移 3、宿主权限提升及转移 4、域控权限提升及转移 基础点 0、为什么我们要学…

算法复杂度的介绍

算法复杂度简介 复杂度也叫渐进复杂度&#xff0c;包括时间复杂度和空间复杂度&#xff0c;用来分析算法执行效率与数据规模之间的增长关系&#xff0c;可以粗略地表示&#xff0c;越高阶复杂度的算法&#xff0c;执行效率越低。常见的复杂度并不多&#xff0c;从低阶到高阶有…

API(时间类)

一、Date类 java.util.Date类 表示特定的瞬间&#xff0c;精确到毫秒。 Date常用方法&#xff1a; public long getTime() 把日期对象转换成对应的时间毫秒值。 public void setTime(long time) 把方法参数给定的毫秒值设…

使用布丰投针法精确计算圆周率

如果在平面上有两条距离为d的平行线&#xff0c;假设如果拿一根长度是L的铁针随机的丢到纸面上去&#xff0c;那么试问铁针与某条直线所相交的概率是多少&#xff0c;假设铁针的长度L是大于平行线的距离d的&#xff0c;这样铁针就不会同时与两条直线所相交了。 添加图片注释&am…