42. 接雨水

207 阅读2分钟

这是我参与11月更文挑战的第22天,活动详情查看:2021最后一次更文挑战

42. 接雨水

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

图片.png

输入: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

来源:力扣(LeetCode) 链接:leetcode-cn.com/problems/tr…

思路

  • 我们可以第一次找到最高的柱子(也就是最大值)
    • 当找到找到最大值以后,我们进行两边分别查找

    • 当进行单侧查找的时候的策略是为:

      • 左边:从左往右找,每次如果下一个柱子比前一个柱子矮的话,就可以进行一次累计加高柱子减去矮柱子的差值

      • 这个差值就是我们每次要求的每一个坑处的存水量

      • 右边:右边就进行与左边相反的操作就可以实现

      • 最终我们得到的res结果集就是每次累加的每个小坑洼处接的雨水量

      当然还有其他的一些方式实现,比如使用单调栈或者更优雅的双指针

class Solution {
    public int trap(int[] height) {
        int index = 0;
        int max = -1;
        int res = 0;
        for (int i = 0; i < height.length; i++) {
            if (height[i] > max) {
                max = height[i];
                index = i;
            }
        }
        for (int left = 0; left < index; left++) {
            for (int i = left+1; i <= index; i++) {
                if (height[left] > height[i]) {
                    res += height[left] - height[i];
                } else {
                    left = i;
                }
            }
        }

        for (int right = height.length - 1; right > index; right--) {
            for (int i = right - 1; i >= index; i--) {
                if (height[right] > height[i]) {
                    res += height[right] - height[i];
                } else {
                    right = i;
                }
            }
        }

        return res;
    }
}