Trapping Rain Water

LeetCode Q 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.

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

Solution

Solution 1: DP

  1. Build two arrays left[] and right[], which stores the maximum height of the water considering only its left and its right, respectively.
  2. Traverse the arrays, calculate Sum(min(left[i], right[i]) - height[i]). This is because the maximum water it can trap depends both on its left and right.

We can use the following graph to explain.

  1. the yellow shade shows the water trapped only considering its left
  2. the green shade shows the water trapped only considering its right
  3. the blue shade shows their intersection, the sum of which is the answer.

Tips: in this question we actually need to consider the influence of both left and right. We simply this type of question by only consider left or right at a time and find the intersection.
Similar Questions: {}, {}

Code:

public int trap(int[] height) {
  if (height == null || height.length == 0) return 0;
  
  int len = height.length;
  int[] left = new int[len];
  int[] right = new int[len];

  left[0] = height[0];
  for (int i = 1; i < len; i++)
    left[i] = Math.max(left[i - 1], height[i]);

  right[len - 1] = height[len - 1];
  for (int i = len - 2; i >= 0; i--)
    right[i] = Math.max(right[i + 1], height[i]);

  int res = 0;
  for (int i = 0; i < len; i++) 
    res += Math.min(left[i], right[i]) - height[i];
  
  return res;
}

Solution 2: Stack

The Key point is We use the stack to store the positions, the corresponding heights of which are ordered decreasingly. So the top int stored in the stack is the pos of local minimum height. When we meet a height, which is higher than the height corresponding ot the top element in the stack, we find the vally, which can trap water.

Using the stack, we fill the water layer by layer, shown as follows.

Code:

public int trap(int[] height) {
  if (height == null || height.length == 0) return 0;
  
  Stack<Integer> stack = new Stack<>();
  int res = 0, curr = 0;
  while (curr < height.length) {
    while (!stack.isEmpty() || height[curr] > height[stack.peek()]) {
      int top = stack.pop(); // we pop the pos of local minimum height
      if (stack.isEmpty) break; 
      int dist = curr - stack.peek() - 1; 
      int height = Math.min(height[curr], height[stack.peek()]) - height[top];
      res += dist * height;
  	}
    stack.push(curr++);
  }
}

Solution 3: Two Pointers

Code:

public int trap(int[] height) {
  if (height == null || height.length == 0) return 0;
  
  int left = 0, right = height.length - 1, res = 0;
  int leftMax = height[left], rightMax = height[right];

  while (left < right) {
    if (height[left] < height[right]) {
      left++;
      leftMax = Math.max(leftMax, height[left]);
      res += (leftMax - height[left]);
    } else {
      right--;
      rightMax = Math.max(rightMax, height[right]);
      res += (rightMax - height[right]);
    }
  }

  return res;
}

   Reprint policy


《Trapping Rain Water》 by Tong Shi is licensed under a Creative Commons Attribution 4.0 International License
 Previous
Decode Ways Decode Ways
LeetCode Q 91 - Decode WaysA message containing letters from A-Z is being encoded to numbers using the following mapping
2019-04-23 Tong Shi
Next 
Edit Distance Edit Distance
LeetCode Q 72 - Edit DistanceGiven two words word1 and word2, find the minimum number of operations required to convert
2019-04-22 Tong Shi
  TOC