leetcode刷题日记-【42. 接雨水】

166 阅读1分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第21天,点击查看活动详情

题目描述

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

 

示例 1:

image.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

题目元素

将题目给定的元素进行转换,可以转成如下要求。给定一个整数数组,代表一组柱状图,数组索引为x坐标,对应索引的值为柱状图高度,求这些柱状图的形成矩形的阴影面积(扣除已有的) 首先要求出所有能形成的矩形,形成矩形的条件为,对边相等,所以当相邻两边的长度不一致时,矩形的高应该是最小的那个值。

解题思路

给定数组最终可以拼接成多个矩形叠在一起,每一层都是个矩形,每一层都可以得到空的阴影面积。然后将所有层的阴影面积进行累加就得到了答案。

可以采用双指针的方法,左右两个指针的分别位于给定数组的起始节点,取最小值为第一层矩形的高,然后遍历内部元素累加元素与这个矩形高度的差值即为当前层的阴影面积;

每一次循环左指针向右移动,右指针向左移动,再获得这两个数的最小值,将这个最小值与上一层的高度进行比较,如果小于上一层的高度则直接指针向内收紧吗,指针移动条件,移动最小的那个;

如果大于上一层的高度,则循环指针内部的元素,将值小于等于这个最小值并大于等于上一层高度的元素与当前矩形高度做差,累加到答案值中;

一直循环,终止条件为左指针大于等于右指针。

代码实现

public static int trap(int[] height) {
    // 设置两个指针
    int left = 0;
    int right = height.length-1;
    // 设置累加值
    int sum = 0;
    // 当前层数
    int level = 0;
    while (left < right) {
        // 终止条件为left>=right
        int nowMin = Math.min(height[left],height[right]);
        if (nowMin > level) {
            // 大于当前层数,则遍历内部元素,累加sum
            for (int i = left;i <= right;i ++) {
                if (height[i] < nowMin) {
                    if (height[i] > level) {
                        // 差值为阴影面积
                        sum += nowMin-height[i];
                    }else {
                        sum += nowMin-level;
                    }
                }
            }
            level = nowMin;
        }
        if (height[left] > height[right]) {
            right--;
        }else if (height[right] > height[left]) {
            left++;
        }else {
            left++;
            right--;
        }
    }
    return sum;
}