友情支持

如果您觉得这个笔记对您有所帮助,看在D瓜哥码这么多字的辛苦上,请友情支持一下,D瓜哥感激不尽,😜

支付宝

微信

有些打赏的朋友希望可以加个好友,欢迎关注D 瓜哥的微信公众号,这样就可以通过公众号的回复直接给我发信息。

wx jikerizhi

公众号的微信号是: jikerizhi因为众所周知的原因,有时图片加载不出来。 如果图片加载不出来可以直接通过搜索微信号来查找我的公众号。

42. 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 is able to trap after raining.

Example:

0042 00

The above elevation map is represented by array [0,1,0,2,1,0,1,3,2,1,2,1]. In this case, 6 units of rain water (blue section) are being trapped. Thanks Marcos for contributing this image!

Input: [0,1,0,2,1,0,1,3,2,1,2,1]
Output: 6

解题分析

0042 01
0042 02
0042 03
0042 04
0042 05
0042 06
  • 一刷

  • 二刷

  • 三刷

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
/**
 * Runtime: 0 ms, faster than 100.00% of Java online submissions for Trapping Rain Water.
 * Memory Usage: 38.3 MB, less than 91.10% of Java online submissions for Trapping Rain Water.
 *
 * Copy from: https://leetcode-cn.com/problems/trapping-rain-water/solution/xiang-xi-tong-su-de-si-lu-fen-xi-duo-jie-fa-by-w-8/[详细通俗的思路分析,多解法 - 接雨水 - 力扣(LeetCode)]
 *
 * @author D瓜哥 · https://www.diguage.com
 * @since 2019-07-26 08:49
 */
public int trap(int[] height) {
    int left = 0, right = height.length - 1;
    int result = 0;
    int leftMax = 0, rightMax = 0;
    while (left < right) {
        if (height[left] < height[right]) {
            if (height[left] >= leftMax) {
                leftMax = height[left];
            } else {
                result += (leftMax - height[left]);
            }
            ++left;
        } else {
            if (height[right] > rightMax) {
                rightMax = height[right];
            } else {
                result += (rightMax - height[right]);
            }
            --right;
        }
    }
    return result;
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
/**
 * @author D瓜哥 · https://www.diguage.com
 * @since 2024-07-31 17:27:46
 */
public int trap(int[] height) {
  int result = 0;
  Deque<Integer> stack = new LinkedList<>();
  stack.push(0);
  for (int r = 1; r < height.length; r++) {
    // 单调递减,则将小的元素都出栈
    while (!stack.isEmpty() && height[stack.peek()] < height[r]) {
      // 递减栈,栈顶最小。与下一个元素比,栈顶小;
      // 上面判断条件,栈顶与当前位置元素比,也是栈顶小
      int mid = stack.pop();
      if (!stack.isEmpty()) {
        int l = stack.peek();
        // 高h 取两边最小的一个。
        // l 是现栈顶元素大,mid 是前栈顶元素最小,当前元素比 mid 大,
        // 所以,形成了一个凹槽,可以接水
        int h = Math.min(height[l], height[r]) - height[mid];
        int w = r - l - 1;
        int area = h * w;
        result += area;
      }
    }
    stack.push(r);
  }
  return result;
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
/**
 * @author D瓜哥 · https://www.diguage.com
 * @since 2024-08-15 19:07:40
 */
public int trap(int[] height) {
  int result = 0;
  int left = 0, right = height.length - 1;
  int lMax = 0, rMax = 0;
  while (left < right) {
    lMax = Math.max(lMax, height[left]);
    rMax = Math.max(rMax, height[right]);
    if (lMax < rMax) {
      result += lMax - height[left];
      left++;
    } else {
      result += rMax - height[right];
      right--;
    }
  }
  return result;
}

思考题

尝试一下动态规划解法!