Trapping Rain Water

Trapping Rain Water is a classic problem in computer science and algorithm design, often used to test a candidate's understanding of data structures and problem-solving skills. The problem can be stated as follows: given an array representing an elevation map where each element is the height of a bar, calculate how much rainwater can be trapped after raining.

To understand this problem and its solution, let's break it down using first principles:

Fundamental Concepts

  1. Array: An array is a fundamental data structure that represents a collection of elements, each identified by an array index. In this problem, the array represents the elevation map.

  2. Water Trapping Logic: The amount of water that can be trapped at a particular index in the array depends on the height of bars to the left and right of it. The water level at a given bar is determined by the lower of the two highest bars on either side.

  3. Volume Calculation: The volume of water above each bar is the difference between the height of water that can be held and the height of the bar itself.

Solving the Problem

  1. Understanding the Input: Consider the array [0, 1, 0, 2, 1, 0, 1, 3, 2, 1, 2, 1]. Here, each number represents the height of a bar. The gaps between these bars are where water can potentially be trapped.

  2. Identifying the Water Trapping Condition: At any given bar, the amount of water trapped above it is determined by finding the highest bars on both the left and right sides, then taking the smaller of these two heights, and subtracting the height of the current bar.

  3. Optimized Solution Approach: A brute force approach would be to iterate over each bar and for each bar, find the highest bar on the left and right, which is time-consuming (O(n^2)). Instead, we can optimize this by using two pointers or arrays to store the highest bars on the left and right for each bar, reducing the time complexity to O(n).

Step-by-Step Algorithm

  1. Initialize Two Arrays: left_max and right_max of the same length as the input array. These will store the maximum height bar to the left and right of each bar.

  2. Fill left_max Array: For each bar, left_max[i] is the maximum of left_max[i-1] and the height of the current bar. This represents the highest bar to the left of the current bar.

  3. Fill right_max Array: Similarly, iterate from the right end of the array to fill the right_max array.

  4. Calculate Trapped Water: Iterate through the array, and for each bar, calculate the water trapped above it as min(left_max[i], right_max[i]) - height[i]. This represents the minimum of the highest bars on either side minus the current bar's height.

  5. Summing Up: The total trapped water is the sum of water trapped above each bar.

Example

Using the example array [0, 1, 0, 2, 1, 0, 1, 3, 2, 1, 2, 1], let’s walk through the steps:

  1. left_max would be [0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3].
  2. right_max would be [3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 1].
  3. Calculating water for each bar, we get [0, 0, 1, 1, 1, 2, 1, 0, 0, 1, 0, 0].
  4. Summing these gives 6, which is the total amount of trapped rainwater.

Conclusion

This problem is a classic example of how understanding and applying fundamental data structures (like arrays) and optimizing solutions with clever use of additional memory (two arrays for left and right max heights) can lead to efficient and effective problem-solving in computer science.

PrevNext