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

news2024/12/25 2:05:49

【力扣】42. 接雨水

给定 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 * 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当前的index
                stack.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.coloradmin.cn/o/899154.html

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

相关文章

AlphaZero能否从围棋和国际象棋飞跃到量子计算?

一项新的研究表明&#xff0c;DeepMind惊人的游戏算法AlphaZero可以帮助释放量子计算的力量和潜力。 自两年多前出现以来&#xff0c;AlphaZero一再证明了其快速学习能力&#xff0c;将自己提升到围棋&#xff0c;国际象棋和将棋&#xff08;日本象棋&#xff09;的特级大师级别…

【数据结构OJ题】用队列实现栈

原题链接&#xff1a;https://leetcode.cn/problems/implement-stack-using-queues/ 目录 1. 题目描述 2. 思路分析 3. 代码实现 1. 题目描述 2. 思路分析 可以用两个队列去实现一个栈&#xff0c;每次始终保持一个队列为空。 入栈相当于给非空队列进行入队操作。 出栈相…

二维码智慧门牌管理系统:打造社区管理新格局

文章目录 前言一、精准数据支持的实现二、便捷办事流程的提升三、多元化服务渠道的拓展四、高效管理和优质服务的提供 前言 在科技的推动下&#xff0c;社区管理正在迎来一场革命性的变革。其中&#xff0c;二维码智慧门牌管理系统崭露头角&#xff0c;成为了社区管理的得力助…

221、仿真-基于51单片机的智能啤酒发酵罐多点温度压力水位排水加水检测报警系统设计(程序+Proteus仿真+配套资料等)

毕设帮助、开题指导、技术解答(有偿)见文未 目录 一、硬件设计 二、设计功能 三、Proteus仿真图 ​编辑 四、程序源码 资料包括&#xff1a; 需要完整的资料可以点击下面的名片加下我&#xff0c;找我要资源压缩包的百度网盘下载地址及提取码。 方案选择 单片机的选择 方…

无涯教程-TensorFlow - 优化器

Optimizers是扩展类&#xff0c;其中包括用于训练特定模型的附加信息&#xff0c;Optimizers类使用给定的参数初始化&#xff0c;用于提高速度和性能&#xff0c;以训练特定模型。 TensorFlow的基本Optimizers是- tf.train.Optimizer 此类在tensorflow/python/training/opti…

shell 脚本的基础

目录 一、什么是shell脚本 二、有哪些表达式 一、变量 二、运算符 三、语句类型分哪几种 一、条件语句 二、分支语句 三、循环语句 四、函数 五、正则表达式 一、标准正则 二、扩展正则 六、文件操作四剑客 七、shell 一、shell是一种命令解释器 二、查看系统中…

esp-idf的电源管理——esp系列芯片的功耗管理硬件

1 芯片的供电 当我们为芯片设计外围电路时,必然会设计供电电路,这是芯片能正常工作的前提。通常是电源电压通过一个稳压电路之后给到芯片的供电引脚。以S3为例,下面是S3的引脚图: 其中以VDD打头的就是供电引脚。比如VDD3P3、VDDA等。供电引脚不止一个,这些供电引脚有什么…

一百六十二、Kettle——Linux上安装的Kettle9.2创建共享资源库

一、目的 在实际的团队开发过程中&#xff0c;不可能将自己的转换、作业和调度等配置存放在自己的电脑中&#xff0c;所以kettle提供资源库的方式&#xff0c;供我们将转换、作业等存储下来&#xff0c;构成一种协作平台。 Kettle支持的资源库类型有三种&#xff1a; 1.Pent…

Python资源楼:40份干货资料+思维导图

盖个楼&#xff0c;收集了社区的Python资料&#xff0c;方便大家查看。 &#xff08;说盖楼好像也不对&#xff0c;叫索引&#xff1f;呵呵不管了&#xff09; 一段小前言&#xff08;首帖要好看点&#xff09;&#xff1a; Python语法简单&#xff0c;很容易上手&#xff0c…

探索大模型时代下的算法工程师前景与发展路径

文章目录 大模型时代的挑战与机遇从算法到工程&#xff1a;技能升级的必要性发展路径与职业规划路径一&#xff1a;深耕研究领域路径二&#xff1a;工程实践与部署路径三&#xff1a;跨界合作与解决复杂问题路径四&#xff1a;教育培训和技术普及 不断学习与更新知识结论 &…

Ubuntu16.04-ros环境搭建笔记=1=

tips&#xff1a;搬运资料&#xff0c;留个记录 安装Ubuntu Ubuntu官网下载地址 安装 虚拟机安装Ubuntu 最好断网安装Ubuntu&#xff0c;可以节约时间 Ubuntu基础设置 Ubuntu换国内源 sudo apt upgrade可以看到镜像已经换过来了 VMwareTool安装 把这个压缩包拖到桌面&…

【以太网通信】RS232 串口转以太网

最近和 RK 研发同事在调试通信接口&#xff0c;排查与定位 RK3399 接收数据出错的问题。FPGA 与 RK3399 之间使用一路 RS232 串口进行通信&#xff0c;由于串口数据没有分包&#xff0c;不方便排查问题&#xff0c;想到可以开发一个 RS232 串口转以太网的工具&#xff0c;将串口…

【C语言】通讯录(文件) -- 详解

⚪前言 前面介绍了【C语言】静态通讯录 -- 详解_炫酷的伊莉娜的博客-CSDN博客和【C语言】动态通讯录 -- 详解_炫酷的伊莉娜的博客-CSDN博客。当通讯录运行起来时&#xff0c;可以对通讯录中的数据进行增加、删除或修改等。此时数据是存放在内存中&#xff0c;当程序退出时&…

不可忽略:冒烟测试到底有多重要?

冒烟测试介绍 冒烟测试一词&#xff0c;来源于电路板测试&#xff1a;电路板拼接或组装完成后&#xff0c;进行通电测试&#xff0c;如果冒烟&#xff0c;则说明存在缺陷。 而软件应用中&#xff0c;对其的定义为&#xff1a;在软件开发过程中的一种针对软件版本包的快速基本…

双亲委派机制,懂吧~ 那什么情况下需要破坏它,知道吗?

一、什么是双亲委派机制&#xff1f; 我们要获得一个类的Class实例&#xff0c;可以采用如下方式&#xff1a; 那么在Class的forName(className)方法中&#xff0c;会根据是谁调用了Class.forName(className)这个方法&#xff0c;那么就获得当时加载了它的那个ClassLoader&…

uniapp选择只选择月份demo效果(整理)

<template><view style"margin-top: 200rpx;"><!-- mode"multiSelector" 多列选择器 --><view><picker :range"years" :value"echoVal" change"yearChange" mode"multiSelector">{…

【面试题】2、Docker和Spring相关

1、Docker是什么&#xff1f; &#xff08;1&#xff09;Docker是一个快速交互、运行应用的技术&#xff0c;可以将程序及其依赖、运行环境一起打包为一个镜像&#xff0c;该镜像可以迁移到任意的Linux操作系统 &#xff08;2&#xff09;运行时利用沙箱机制形成隔离容器&…

【JasperReports笔记04】如何使用Jasper Studio制作父子报表,并且通过Java + Parameters参数填充模板文件

这篇文章&#xff0c;主要介绍如何使用Jasper Studio制作父子报表&#xff0c;并且通过Java Parameters参数填充模板文件。 目录 一、JasperReports实现父子报表 1.1、运行效果 1.2、制作模板 &#xff08;1&#xff09;制作子报表 &#xff08;2&#xff09;制作子报表的…

计算机竞赛 图像检索算法

文章目录 1 前言2 图像检索介绍(1) 无监督图像检索(2) 有监督图像检索 3 图像检索步骤4 应用实例5 最后 1 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 图像检索算法 该项目较为新颖&#xff0c;适合作为竞赛课题方向&#xff0c;学长非常推荐&#xff…

0101读写分离测试-jdbc-shardingsphere-中间件

文章目录 1 前言2、创建SpringBoot程序2.1、创建项目2.2、添加依赖2.3、生成实体类、service与Mapper1.5、配置读写分离 2、测试2.1、读写分离测试2.2、事务测试2.3、负载均衡测试 结语 1 前言 shardingshpere-jdbc定位为轻量级 Java 框架&#xff0c;在 Java 的 JDBC 层提供的…