【LeetCode】No.42. Trapping Rain Water -- Java Version

79 阅读1分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第21天。

题目链接: leetcode.com/problems/tr…

1. 题目介绍(Trapping Rain Water)

Given n non-negative integers representing an elevation map where the width of each bar is 1, compute how much water it can trap after raining.

【Translate】: 给定n个非负整数,表示一个高度图,其中每个条的宽度为1,计算它在下雨后可以捕获多少水。

【测试用例】: example1example2

【约束】:

constraints

2. 题解

2.1 Brute-Force

  代码来自junhaowanggg的 [Java] Detailed Explanations & Illustrations (divide-and-conquer, DP, two pointers),以[4,2,0,3,2,5]为例,暴力求解从数组0索引开始,逐步寻找两边最大的墙,然后通过Math.min(leftMax, rightMax)减去当前值得到该位置所能存储的水量,直至结束。 demo1

class Solution {
    public int trap(int[] height) {
      int n = height.length;
      int totalWater = 0;
      for (int k = 0; k < n; ++k) {
        int leftMax = 0;
        for (int i = 0; i <= k - 1; ++i) {
          leftMax = Math.max(leftMax, height[i]);
        }
        int rightMax = 0;
        for (int i = k + 1; i < n; ++i) {
          rightMax = Math.max(rightMax, height[i]);
        }
        int water = Math.min(leftMax, rightMax) - height[k];
        totalWater += (water > 0) ? water : 0;
      }
      return totalWater;
    }
}

case1

2.2 Two pointer

  • 在这里,我们将使用两个指针l和r来遍历数组,并使用leftmax和rightmax来存储向左和向右的最大值。
  • 我们需要明白的是,只有在有山谷时,我们才能在总和中添加水。
  • 因此,当遍历时,如果我们发现高度[l]小于或等于高度[r],那么我们就知道,只有height[l]也小于leftmax时,才能存储水。

其实这就相当于左右开工,逐渐向中间逼近。 demo2

class Solution {
    public int trap(int[] height) {
        int n = height.length;
        if(n <= 2) return 0;
        int sum = 0;

        int l = 0, r = n - 1;
        int leftMax = 0, rightMax = 0;
        while(l < r) {
            if(height[l] <= height[r]) {
                if(height[l] >= leftMax) leftMax = height[l];
                else {
                    sum += leftMax - height[l];
                }
                l++;
            } else {
                if(height[r] >= rightMax) rightMax = height[r];
                else {
                    sum += rightMax - height[r];
                }
                r--;
            }
        }
        return sum;
    }
}

case2