Knowledge Guide
HomeDSACompany Practice

hard Trapping Rain Water

Problem Statement

Given an array of positive integers height, where height[i] represents the height of the bar in the elevation map and each bar has width 1, return how much water it can trap after raining.

Examples

Example 1:

Image
Image

Example 2:

Image
Image

Example 3:

Image
Image

Constraints:

Try it yourself

Try solving this question here:

✅ Solution Trapping Rain Water

Problem Statement

Given an array of positive integers height, where height[i] represents the height of the bar in the elevation map and each bar has width 1, return how much water it can trap after raining.

Examples

Example 1:

  • Input: height = [4, 0, 3, 0, 2]
Image
Image
  • Expected Output: 5
  • Justification: The first and third bars form a container that traps 3 units of water. The third and fifth bars trap an additional 2 units. Therefore, the total trapped water is 5 units.

Example 2:

  • Input: height = [1, 2, 1, 2, 1]
Image
Image
  • Expected Output: 1
  • Justification: Water is only trapped between the second and fourth bars, holding 1 unit of water.

Example 3:

  • Input: height = [3, 1, 2, 4, 0, 1, 3]
Image
Image
  • Expected Output: 8
  • Justification: The first, and fourth bars trap 3 units of water. The fourth, and seventh bars trap an additional 5 units. The total is 8 units of trapped water.

Constraints:

  • n == height.length
  • 1 <= n <= 2 * 104
  • 0 <= height[i] <= 105

Solution

To solve this problem, we'll employ a two-pointer technique, which is efficient for this kind of linear space problem. This approach works by iterating over the elevation map from both ends towards the center, calculating the potential water trap at each step. We believe this method is effective because it allows us to compute the maximum water trapped by considering the minimum height between two points at a time, which is the limiting factor for water trapping. This way, we can efficiently calculate the trapped water without needing to consider all possible containers formed between bars, significantly reducing the computational complexity.

The essence of our approach is to keep track of the left and right maximum heights as we move the pointers towards the center. By comparing these heights, we can determine the amount of water that can be trapped at each step based on the difference between the current height and the minimum of the two maximum heights. This strategy ensures that we only need to pass through the elevation map once, making it a highly efficient solution.

Step-by-Step Algorithm

  1. Initialize Pointers and Variables:

    • Set two pointers, left and right, to point at the start and end of the array, respectively.
    • Initialize two variables, leftMax and rightMax, to 0. These will keep track of the maximum height encountered so far from the left and right sides.
    • Initialize a variable waterTrapped to 0. This will accumulate the total amount of water trapped.
  2. Iterate Over the Array:

    • While the left pointer is less than the right pointer, do the following:
      • Compare the height at the left pointer with the height at the right pointer.
      • If the height at left is less than the height at right:
        • Update leftMax to the maximum of leftMax and the height at the current left position.
        • Calculate the water trapped at the current left position as the difference between leftMax and the height at left, and add it to waterTrapped. If the difference is negative, add 0 instead.
        • Increment the left pointer to move it towards the center.
      • Else (if the height at right is less than or equal to the height at left):
        • Update rightMax to the maximum of rightMax and the height at the current right position.
        • Calculate the water trapped at the current right position as the difference between rightMax and the height at right, and add it to waterTrapped. If the difference is negative, add 0 instead.
        • Decrement the right pointer to move it towards the center.
  3. Return the Total Water Trapped:

    • After the loop terminates (when left meets right), return the waterTrapped variable as the total amount of water trapped.

Algorithm Walkthrough

Let's consider the input: height = [3, 1, 2, 4, 0, 1, 3].

  1. Initialization:

    • left = 0, right = 6, leftMax = 0, rightMax = 0, waterTrapped = 0
  2. First Iteration:

    • left = 0, right = 6, height[left] = 3, height[right] = 3
    • Since height[left] is not less than height[right], we look to update rightMax and calculate water for right.
    • rightMax is updated to 3.
    • No water is trapped because rightMax equals height[right].
    • Decrement right.
    • waterTrapped = 0.
  3. Second Iteration:

    • left = 0, right = 5, height[left] = 3, height[right] = 1
    • height[left] is greater than height[right], so we update rightMax if needed and calculate water for right.
    • rightMax remains 3.
    • Water trapped at right = 5 is 3 - 1 = 2.
    • Decrement right.
    • waterTrapped = 2.
  4. Third Iteration:

    • left = 0, right = 4, height[left] = 3, height[right] = 0
    • rightMax remains 3.
    • Water trapped at right = 4 is 3 - 0 = 3.
    • Decrement right.
    • waterTrapped = 5.
  5. Fourth Iteration:

    • left = 0, right = 3, height[left] = 3, height[right] = 4
    • leftMax remains 3.
    • No water is trapped because leftMax equals height[left].
    • Increment left.
    • waterTrapped = 5.
  6. Fifth Iteration:

    • left = 1, right = 3, height[left] = 1, height[right] = 4
    • leftMax remains 3.
    • Water trapped at left = 1 is 3 - 1 = 2.
    • Increment left.
    • waterTrapped = 7.
  7. Sixth Iteration:

    • left = 2, right = 3, height[left] = 2, height[right] = 4
    • leftMax remains 3.
    • Water trapped at left = 2 is 3 - 2 = 1.
    • Increment left.
    • waterTrapped = 8.
  8. Seventh Iteration:

    • The loop terminates because left is no longer less than right.
  9. Conclusion:

    • The total waterTrapped is 8.

Code

java
public class Solution {

  public int trap(int[] height) {
    int left = 0, right = height.length - 1; // Initialize two pointers
    int leftMax = 0, rightMax = 0; // Track max heights from both sides
    int waterTrapped = 0; // Accumulate trapped water

    while (left < right) {
      if (height[left] < height[right]) {
        leftMax = Math.max(leftMax, height[left]); // Update left max
        waterTrapped += Math.max(0, leftMax - height[left]); // Trap water if possible
        left++; // Move left pointer inward
      } else {
        rightMax = Math.max(rightMax, height[right]); // Update right max
        waterTrapped += Math.max(0, rightMax - height[right]); // Trap water if possible
        right--; // Move right pointer inward
      }
    }

    return waterTrapped; // Return total trapped water
  }

  public static void main(String[] args) {
    Solution solution = new Solution();
    // Test the algorithm with example inputs
    System.out.println(solution.trap(new int[] { 4, 0, 3, 0, 2 })); // Example 1
    System.out.println(solution.trap(new int[] { 1, 2, 1, 2, 1 })); // Example 2
    System.out.println(solution.trap(new int[] { 3, 1, 2, 4, 0, 1, 3 })); // Example 3
  }
}

Complexity Analysis

Time Complexity

The time complexity of the algorithm is , where n is the number of elements in the input array. This efficiency is achieved because the algorithm makes a single pass through the array, with two pointers moving towards the center from both ends. Each element is accessed exactly once to update the trapped water calculation and the left/right max heights, ensuring linear time complexity.

Space Complexity

The space complexity of the algorithm is . This is because the algorithm uses a constant amount of extra space regardless of the input size.

🤖 Don't fully get this? Learn it with Claude

Stuck on Trapping Rain Water? Open Claude, copy a block below, and it'll teach you this exact concept — visually and interactively.

🪜 Hint ladder (no spoilers)

Progressively stronger hints — you still solve it.

I'm working on the problem **Trapping Rain Water** (DSA). Give me a HINT LADDER: start with the tiniest nudge, then wait. Only reveal the next, stronger hint when I ask. Do NOT show the full solution unless I type 'show solution'. Keep me doing the thinking. If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.
🎨 Explain the approach visually

See the technique, not just code.

Explain the optimal approach to **Trapping Rain Water** with a VISUAL walkthrough: trace it on a small concrete example using ASCII art / a step-by-step diagram, narrate what changes each step, then give time & space complexity with a one-line derivation. If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.
🔍 Review my solution

Catch bugs, edge cases, sub-optimality.

I'll paste my solution to **Trapping Rain Water**. Review it for correctness, missed edge cases, and time/space complexity, then coach me toward the optimal — don't just rewrite it. Ask me to paste my code now. If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.
🔁 Drill the pattern

Lock in recognition with look-alikes.

Give me 2 problems that use the SAME underlying pattern as **Trapping Rain Water**. For each, let me attempt first, then review my answer and name the trigger signal that reveals the pattern. If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.

📝 My notes