2440 字
约 8 分钟
11
Java 版 LeetCode 刷题笔记:042.接雨水
无标签

Java 版 LeetCode 刷题笔记:042.接雨水

作者:沉默王二
发布时间:2022-09-19T21:51:17.229+0800


042.接雨水

题意

给定 n 个非负整数表示每个宽度为 1 的柱子的高度图,计算按此排列的柱子,下雨之后能接多少雨水。

难度

困难

示例

输入:height = [0,1,0,2,1,0,1,3,2,1,2,1]

解释:上面是由数组 [0,1,0,2,1,0,1,3,2,1,2,1] 表示的高度图,在这种情况下,可以接 6 个单位的雨水(蓝色部分表示雨水)。 

分析

本题为困难程度,但不要怕,我们可以抽丝剥茧的将重要的信息剥离出来,一步一步解决它。

想一想,能接到雨水,那么一个 能接雨水的区域 肯定是由 左边界、右边界和底来构成的。我们要做的就是快速找到这三个元素。

假如我们现在到了i这个位置,那么如果它能够作为底层的话,它的左边和右边肯定都是比它高的。

也就是说,如果这个点能够作为底层,那么它 这一列 能够接的雨水,就是由它左右边界的最小值来确定的。

而它的边界——不就是左边的最大值和右边的最大值吗?

这个点一旦想通了,这道题瞬间就不再是一道困难题,而是简单题了。

我们来回顾一遍整个算法的过程:

  • 将 “雨水” 分成一列一列来计算
  • 该列能累计的 “雨水” 由maxLef[i]和maxRig[i]的最小值来决定——即min(maxLef[i],maxRig[i]) - height[i],如果左右两边的最小值比该列的高度小,则说明该列不能接雨水,直接跳过。

这样子我们就能够轻轻松松的解决这道困难题了。

class Solution {

        int ans = 0;        int rigMax[] = new int[height.length];        int maxx = 0;        for(int i = height.length - 1;i >= 0;i--){            rigMax[i] = maxx;            maxx = Math.max(maxx,height[i]);        }        maxx = 0;        int lefMax[] = new int[height.length];        for(int i = 0;i < height.length;i++){            lefMax[i] = maxx;            maxx = Math.max(maxx,height[i]);        }        for(int i = 0;i < height.length;i++)            ans += Math.max(Math.min(lefMax[i],rigMax[i]) - height[i],0);        return ans;    }}

时间复杂度:,因为我们只是将整个数组遍历了三遍。

而且效率也非常不错。

总结

本题我们将接雨水的容器拆分成一列一列来计算,联系一下现实生活,也不难得出结论,一个水塘的能够蓄水的高度其实就是水面到水塘底的距离,最大容量是由两边的最低高度确定的。所以本题虽然是 hard 模式,但不用想得太复杂,仔细分析以下,就可以得出破题之法。

力扣链接:https://leetcode.cn/problems/trapping-rain-water/

一步一个脚印

不积跬步无以至千里,不积小流无以成江海。LeetCode - 100天从算法小白到卷王正式启动了,我们计划周一到周五至少每天更新一篇,周六周日更新一篇,目标 300 道 LeetCode 经典题。

PDF 版本目前只针对**二哥编程星球 的球友开放,如果你也想一起打卡学习算法的话,戳链接 **加入我们吧。

一个人可以走得很快,但一群人才能走得更远。二哥编程星球 (目前已有 810 多名球友加入)里面的每个球友都非常的友善,除了鼓励你,还会给你提出合理的建议,一起冲!

042.接雨水

题意

给定 n 个非负整数表示每个宽度为 1 的柱子的高度图,计算按此排列的柱子,下雨之后能接多少雨水。

难度

困难

示例

输入:height = [0,1,0,2,1,0,1,3,2,1,2,1]

解释:上面是由数组 [0,1,0,2,1,0,1,3,2,1,2,1] 表示的高度图,在这种情况下,可以接 6 个单位的雨水(蓝色部分表示雨水)。 

分析

本题为困难程度,但不要怕,我们可以抽丝剥茧的将重要的信息剥离出来,一步一步解决它。

想一想,能接到雨水,那么一个 能接雨水的区域 肯定是由 左边界、右边界和底来构成的。我们要做的就是快速找到这三个元素。

假如我们现在到了i这个位置,那么如果它能够作为底层的话,它的左边和右边肯定都是比它高的。

也就是说,如果这个点能够作为底层,那么它 这一列 能够接的雨水,就是由它左右边界的最小值来确定的。

而它的边界——不就是左边的最大值和右边的最大值吗?

这个点一旦想通了,这道题瞬间就不再是一道困难题,而是简单题了。

我们来回顾一遍整个算法的过程:

  • 将 “雨水” 分成一列一列来计算
  • 该列能累计的 “雨水” 由maxLef[i]和maxRig[i]的最小值来决定——即min(maxLef[i],maxRig[i]) - height[i],如果左右两边的最小值比该列的高度小,则说明该列不能接雨水,直接跳过。

这样子我们就能够轻轻松松的解决这道困难题了。

class Solution {

        int ans = 0;        int rigMax[] = new int[height.length];        int maxx = 0;        for(int i = height.length - 1;i >= 0;i--){            rigMax[i] = maxx;            maxx = Math.max(maxx,height[i]);        }        maxx = 0;        int lefMax[] = new int[height.length];        for(int i = 0;i < height.length;i++){            lefMax[i] = maxx;            maxx = Math.max(maxx,height[i]);        }        for(int i = 0;i < height.length;i++)            ans += Math.max(Math.min(lefMax[i],rigMax[i]) - height[i],0);        return ans;    }}

时间复杂度:,因为我们只是将整个数组遍历了三遍。

而且效率也非常不错。

总结

本题我们将接雨水的容器拆分成一列一列来计算,联系一下现实生活,也不难得出结论,一个水塘的能够蓄水的高度其实就是水面到水塘底的距离,最大容量是由两边的最低高度确定的。所以本题虽然是 hard 模式,但不用想得太复杂,仔细分析以下,就可以得出破题之法。

力扣链接:https://leetcode.cn/problems/trapping-rain-water/

一步一个脚印

不积跬步无以至千里,不积小流无以成江海。LeetCode - 100天从算法小白到卷王正式启动了,我们计划周一到周五至少每天更新一篇,周六周日更新一篇,目标 300 道 LeetCode 经典题。

PDF 版本目前只针对**二哥编程星球 的球友开放,如果你也想一起打卡学习算法的话,戳链接 **加入我们吧。

一个人可以走得很快,但一群人才能走得更远。二哥编程星球 (目前已有 810 多名球友加入)里面的每个球友都非常的友善,除了鼓励你,还会给你提出合理的建议,一起冲!

042.接雨水

题意

给定 n 个非负整数表示每个宽度为 1 的柱子的高度图,计算按此排列的柱子,下雨之后能接多少雨水。

难度

困难

示例

输入:height = [0,1,0,2,1,0,1,3,2,1,2,1]

解释:上面是由数组 [0,1,0,2,1,0,1,3,2,1,2,1] 表示的高度图,在这种情况下,可以接 6 个单位的雨水(蓝色部分表示雨水)。 

分析

本题为困难程度,但不要怕,我们可以抽丝剥茧的将重要的信息剥离出来,一步一步解决它。

想一想,能接到雨水,那么一个 能接雨水的区域 肯定是由 左边界、右边界和底来构成的。我们要做的就是快速找到这三个元素。

假如我们现在到了i这个位置,那么如果它能够作为底层的话,它的左边和右边肯定都是比它高的。

也就是说,如果这个点能够作为底层,那么它 这一列 能够接的雨水,就是由它左右边界的最小值来确定的。

而它的边界——不就是左边的最大值和右边的最大值吗?

这个点一旦想通了,这道题瞬间就不再是一道困难题,而是简单题了。

我们来回顾一遍整个算法的过程:

  • 将 “雨水” 分成一列一列来计算
  • 该列能累计的 “雨水” 由maxLef[i]和maxRig[i]的最小值来决定——即min(maxLef[i],maxRig[i]) - height[i],如果左右两边的最小值比该列的高度小,则说明该列不能接雨水,直接跳过。

这样子我们就能够轻轻松松的解决这道困难题了。

class Solution {

        int ans = 0;        int rigMax[] = new int[height.length];        int maxx = 0;        for(int i = height.length - 1;i >= 0;i--){            rigMax[i] = maxx;            maxx = Math.max(maxx,height[i]);        }        maxx = 0;        int lefMax[] = new int[height.length];        for(int i = 0;i < height.length;i++){            lefMax[i] = maxx;            maxx = Math.max(maxx,height[i]);        }        for(int i = 0;i < height.length;i++)            ans += Math.max(Math.min(lefMax[i],rigMax[i]) - height[i],0);        return ans;    }}

时间复杂度:,因为我们只是将整个数组遍历了三遍。

而且效率也非常不错。

总结

本题我们将接雨水的容器拆分成一列一列来计算,联系一下现实生活,也不难得出结论,一个水塘的能够蓄水的高度其实就是水面到水塘底的距离,最大容量是由两边的最低高度确定的。所以本题虽然是 hard 模式,但不用想得太复杂,仔细分析以下,就可以得出破题之法。

力扣链接:https://leetcode.cn/problems/trapping-rain-water/

一步一个脚印

不积跬步无以至千里,不积小流无以成江海。LeetCode - 100天从算法小白到卷王正式启动了,我们计划周一到周五至少每天更新一篇,周六周日更新一篇,目标 300 道 LeetCode 经典题。

PDF 版本目前只针对**二哥编程星球 的球友开放,如果你也想一起打卡学习算法的话,戳链接 **加入我们吧。

一个人可以走得很快,但一群人才能走得更远。二哥编程星球 (目前已有 810 多名球友加入)里面的每个球友都非常的友善,除了鼓励你,还会给你提出合理的建议,一起冲!

            知识星球
            
    
    
        
        扫码加入星球
        查看更多优质内容
    
    https://wx.zsxq.com/mweb/views/joingroup/join_group.html?group_id=15522885221412
Java 版 LeetCode 刷题笔记:042.接雨水
https://clxhxhhr.top/posts/2506/
作者
clxstart
发布于
2026-09-19
许可协议
CC BY-NC-SA 4.0
评论
0 条
还没有评论,先写一条吧。