力扣-hot100(接雨水-双指针)

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 个单位的雨水(蓝色部分表示雨水)。

n == height.length 1 <= n <= 2 * 104 0 <= height[i] <= 105

思路:双指针分别指向两侧,不断向中间靠近,如果靠近的过程中右边最长的柱子长度 大于 左边最长的柱子长度,短板效应,那么就可以计算左边当前的空穴可以装多少水了【是由左边最长的柱子和左边当前柱子的长度差决定的(leftMax - height[left])】

以计算左侧积水为例的三种情况:

1、如果当前的左柱子就是最长那么积攒的雨水: leftMax - height[left] = 0,满足要求

2、当前左柱子 > 左侧目前拿到的最长柱子 这种情况不可能存在,因为选最左侧长柱子肯定要包含当前柱子,就是情况一,满足要求

3、当前左柱子 < 左侧目前拿到的最长柱子 正常计算leftMax - height[left],满足要求。 dangdangdang

class Solution {
    public int trap(int[] height) {
        // 左右指针分别用来计算当前的柱子能积攒多少雨水,左右最大长度指针用来维护当下可以算哪一侧的雨水
        int left = 0, right = height.length - 1;
        int leftMax = height[left], rightMax = height[right];
        // 一共能积攒多少雨水
        int res = 0;
        // 最两侧的柱子他的其中一侧没有柱子,肯定是形成不了雨水的
        left ++;
        right --;
        while(right >= left){
            // 选出当前左右边最长的那根, 这样才知道应该去计算哪一侧的
            leftMax = Math.max(leftMax, height[left]);
            rightMax = Math.max(rightMax, height[right]);
            // 计算两侧中当前的柱子积攒的雨水
            if(leftMax < rightMax){
                res += leftMax - height[left];
                left ++;
            }
            else {
                res += rightMax - height[right];
                right --;
            }
        }
        return res;
    }
}

你可能感兴趣的:(LeetCode,-,Hot100,leetcode,算法,数据结构)