通俗易懂帮你解决力扣热题100中的42. 接雨水

42. 接雨水

好多天没有更新算法题了,前段时间在为一个软件设计大赛准备,一直在开发软件,所以没写算法题,不过这几天一直在写,也为6月10号的蓝桥杯做准备。多余的不说了,接下来请看题

给定 n 个非负整数表示每个宽度为 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

这道题是力扣hot100题双指针的一道困难题,我刚开始做也有思路,但是没有写出来好的代码,然后看了别人的题解做出来了,当然我也总结一下我的做法。

解题思路

  • 先给大家分析一下,怎么样我们才能接到雨水呢,当然是当所在位置的高度小于左边跟右边的高度时,才能接到Math.min(左边高度,右边高度) - 当前位置高度的雨水,比如说下图,能接到的水就是 1

在这里插入图片描述

  • 那么关于本题该怎么解决呢?其实也就是找每个位置能接多少水,然后把所有的加起来,不就是总的接水量吗。

  • 那么我们要知道每个位置左边的高度右边的高度。那么这所说的不仅仅是该位置相邻的左右两个位置高度,而是所有左边最高的高度,所有右边位置最高的高度。比如下图
    在这里插入图片描述

  • 因此,我们需要遍历题中数组,需要一个指针从左遍历,并寻找leftMax,另一个指针从右遍历,寻找rightMax.

具体java代码如下:

class Solution {
    public int trap(int[] height) {
        int left = 0;
        int right = height.length - 1;
        int leftMax = 0;
        int rightMax = 0;
        int sum = 0;
        while(left < right){
            leftMax = Math.max(leftMax, height[left]);
            rightMax = Math.max(rightMax, height[right]);
            if(height[left] < height[right]){
                //height[left] < height[right] 的时候 leftmax < rightmax
                sum += (leftMax - height[left]);
                left++;
            }else{
                sum += (rightMax - height[right]);
                right--;
            }
        }
        return sum;
    }
}

或许有人疑问为什么height[left] < height[right]的时候leftmax < rightmax。我给大家举个反例就能明白了。看下图

在这里插入图片描述

大家迷惑可能就是这个图的样子,height[left] = 2 < height[righe] = 4 但是leftMax = 5 > rightMax = 4。这个图确实是这个样子的。

但是我们去看我们的程序,假如说从左第一个开始

  1. leftMax = height[left] = 5。 rightMax = height[right] = 4
  2. 这时我们该进行else部分,是right–。
  3. right向左移动一位,那么left不动,所以不会出现我们的上图中的情况的。

大家可以按照代码推一推,推导一遍自然就明白了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值