leetcode题解-接雨水问题

2024-08-27 04:58
文章标签 leetcode 问题 题解 雨水

本文主要是介绍leetcode题解-接雨水问题,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

文章目录

  • 问题描述
  • 问题抽象
  • 问题关键点分析
  • 思路一
  • 思路二
  • 结束语

雨纷纷,旧故里草木深。
我听闻,你始终一个人。

今天忘忧跟大家一起探索一个跟雨水有关的算法,题目来源leetcode。

问题描述

给定 n 个非负整数表示每个宽度为 1 的柱子的高度图,计算按此排列的柱子,下雨之后能接多少雨水。下面是由数组 [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

问题抽象

这个问题可以抽象成一个网格,共有m(最高的柱子) * n(柱子数量)个格子,求哪些格子可以装水。如下图所示:

问题关键点分析

  • 本题的关键点在于,具备什么条件的格子可以存水?
  • 图中3 * 12个格子共被分为了三类。黑色部分已被柱子所占据,故不能存水。白色部分的左侧或者右侧,至少有一侧没被柱子挡住,最终水会流失掉。蓝色部分,未被柱子占据且左右侧均有柱子可以挡住水的流失,故能存水。由此得出结论,能存水的位置必须具备两个条件:(1) 空间未被柱子占据;(2) 左右两侧均有比当前位置高的柱子。

思路一

  1. 求出最高的柱子和最低的柱子;
  2. 从最低的柱子的高度开始遍历,遍历当前高低下所有的位置(方格),判断当前方格是否没有柱子且左右均有大于等于当前位置高度的柱子。
  3. 层级加1,循环2的操作,直至层级大于最高柱子的层级结束。

代码实现:

public static int trap(int[] height) {//1. 求出最高的和最低的柱子if(height.length == 0){return 0;}int min = height[0];int max = height[0];for (int i : height) {if(i > max) {max = i;}if(i < min){min = i;}}//记述,表示总计可以接住的雨水数量int sum = 0;//从最底层开始遍历,遍历到大于最高层结束for (int i = min; i <= max; i++){//遍历当前层级的所有位置(方格)//省略掉第一个位置和最后一个位置的判断,因为第一个位置和最后一个位置不会存水for(int j = 1; j < height.length - 1; j++){//判断当前位置是否被柱子占据if(height[j] < i){//标示左侧是否有大于等于当前位置的柱子boolean left = false;boolean right = false;for (int k = 0; k < height.length; k++){//判断左侧是否有柱子大于等于当前位置if(k < j && height[k] >= i){left = true;}//判断右侧是否有柱子大于等于当前位置if(k > j && height[k] >= i){right = true;}}//如果左右均有柱子遮挡,总数量加一if(left && right){sum ++;}}}}return sum;
}

运行结果:

ps:搞定!but,提交leetcode后,发现代码欠佳呀~

死在了最后一个测试用例上。

思路二

  1. 找出最高的柱子的高度和位置。
  2. 对最高柱子左侧的所有空格做判断,此时只需要判断左侧有没有比当前位置高的即可,右侧同理;此时的时间复杂度仅仅为O(n),远小于思路一的O(n^2);

代码实现:

public static int trap(int[] height){if(height.length == 0){return 0;}//1. 遍历一遍,找出最高柱子的坐标int maxIndex = 0;for (int i = 0; i < height.length; i++) {if(height[i] > height[maxIndex]){maxIndex = i;}}int sum= 0;//遍历最高柱左侧if(maxIndex > 1){int leftMax = 0;for (int i = 1; i < maxIndex; i++){//当前柱子高度小于左侧最高柱if (height[i] < height[leftMax]) {//该位置可以存放height[leftMax] - height[i]的水sum += height[leftMax] - height[i];}else{//否则标记当前坐标为左侧最高柱leftMax = i;}}}//遍历最高柱左侧if(maxIndex < height.length - 2){int rightMax = height.length - 1;//从最右侧开始,每次往左移动一个位置,遍历到最高柱for (int i = height.length - 2; i > maxIndex; i--){if (height[i] < height[rightMax]) {sum += height[rightMax] - height[i];}else{rightMax = i;}}}return sum;
}

运行结果:

提交结果:

搞定!当然,这个思路不一定是最优解,这个算法本身也存在这一些可以优化的地方,如果大家感兴趣,可以深入研究,在此忘忧就不再继续深入了。

PS:忘忧很期待与大家的交流,大家有任何问题可以通过公众号给忘忧留言,忘忧都会认真回复的,期望与大家在交流中一起成长!

结束语

忘忧的个人公众号,欢迎大家一起交流:算法之灵魂拷问

长风破浪会有时,直挂云帆济沧海!

这篇关于leetcode题解-接雨水问题的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1110703

相关文章

线上Java OOM问题定位与解决方案超详细解析

《线上JavaOOM问题定位与解决方案超详细解析》OOM是JVM抛出的错误,表示内存分配失败,:本文主要介绍线上JavaOOM问题定位与解决方案的相关资料,文中通过代码介绍的非常详细,需要的朋... 目录一、OOM问题核心认知1.1 OOM定义与技术定位1.2 OOM常见类型及技术特征二、OOM问题定位工具

Vue3绑定props默认值问题

《Vue3绑定props默认值问题》使用Vue3的defineProps配合TypeScript的interface定义props类型,并通过withDefaults设置默认值,使组件能安全访问传入的... 目录前言步骤步骤1:使用 defineProps 定义 Props步骤2:设置默认值总结前言使用T

Web服务器-Nginx-高并发问题

《Web服务器-Nginx-高并发问题》Nginx通过事件驱动、I/O多路复用和异步非阻塞技术高效处理高并发,结合动静分离和限流策略,提升性能与稳定性... 目录前言一、架构1. 原生多进程架构2. 事件驱动模型3. IO多路复用4. 异步非阻塞 I/O5. Nginx高并发配置实战二、动静分离1. 职责2

解决升级JDK报错:module java.base does not“opens java.lang.reflect“to unnamed module问题

《解决升级JDK报错:modulejava.basedoesnot“opensjava.lang.reflect“tounnamedmodule问题》SpringBoot启动错误源于Jav... 目录问题描述原因分析解决方案总结问题描述启动sprintboot时报以下错误原因分析编程异js常是由Ja

MySQL 表空却 ibd 文件过大的问题及解决方法

《MySQL表空却ibd文件过大的问题及解决方法》本文给大家介绍MySQL表空却ibd文件过大的问题及解决方法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考... 目录一、问题背景:表空却 “吃满” 磁盘的怪事二、问题复现:一步步编程还原异常场景1. 准备测试源表与数据

解决Nginx启动报错Job for nginx.service failed because the control process exited with error code问题

《解决Nginx启动报错Jobfornginx.servicefailedbecausethecontrolprocessexitedwitherrorcode问题》Nginx启... 目录一、报错如下二、解决原因三、解决方式总结一、报错如下Job for nginx.service failed bec

SysMain服务可以关吗? 解决SysMain服务导致的高CPU使用率问题

《SysMain服务可以关吗?解决SysMain服务导致的高CPU使用率问题》SysMain服务是超级预读取,该服务会记录您打开应用程序的模式,并预先将它们加载到内存中以节省时间,但它可能占用大量... 在使用电脑的过程中,CPU使用率居高不下是许多用户都遇到过的问题,其中名为SysMain的服务往往是罪魁

MySQ中出现幻读问题的解决过程

《MySQ中出现幻读问题的解决过程》文章解析MySQLInnoDB通过MVCC与间隙锁机制在可重复读隔离级别下解决幻读,确保事务一致性,同时指出性能影响及乐观锁等替代方案,帮助开发者优化数据库应用... 目录一、幻读的准确定义与核心特征幻读 vs 不可重复读二、mysql隔离级别深度解析各隔离级别的实现差异

C++ vector越界问题的完整解决方案

《C++vector越界问题的完整解决方案》在C++开发中,std::vector作为最常用的动态数组容器,其便捷性与性能优势使其成为处理可变长度数据的首选,然而,数组越界访问始终是威胁程序稳定性的... 目录引言一、vector越界的底层原理与危害1.1 越界访问的本质原因1.2 越界访问的实际危害二、基

Python多线程应用中的卡死问题优化方案指南

《Python多线程应用中的卡死问题优化方案指南》在利用Python语言开发某查询软件时,遇到了点击搜索按钮后软件卡死的问题,本文将简单分析一下出现的原因以及对应的优化方案,希望对大家有所帮助... 目录问题描述优化方案1. 网络请求优化2. 多线程架构优化3. 全局异常处理4. 配置管理优化优化效果1.