githubEdit

02. Trapping Rain Water

βœ… GFG solution to Trapping Rain Water: calculate maximum water trapped between blocks using efficient two-pointer technique. πŸš€

The problem can be found at the following link: πŸ”— Question Linkarrow-up-right

🧩 Problem Description

Given an array arr[] with non-negative integers representing the height of blocks. If the width of each block is 1, compute how much water can be trapped between the blocks during the rainy season.

πŸ“˜ Examples

Example 1

Input: arr[] = [3, 0, 1, 0, 4, 0, 2]
Output: 10
Explanation: Total water trapped = 0 + 3 + 2 + 3 + 0 + 2 + 0 = 10 units.

Example 2

Input: arr[] = [3, 0, 2, 0, 4]
Output: 7
Explanation: Total water trapped = 0 + 3 + 1 + 3 + 0 = 7 units.

Example 3

Input: arr[] = [1, 2, 3, 4]
Output: 0
Explanation: We cannot trap water as there is no height bound on both sides.

Example 4

πŸ”’ Constraints

  • $1 < \text{arr.size()} < 10^5$

  • $0 < \text{arr}[i] < 10^3$

βœ… My Approach

The optimal solution uses Two-Pointer Technique:

Two-Pointer Strategy

  1. Key Insight:

    • Water trapped at any position depends on the minimum of maximum heights on its left and right.

    • Formula: water[i] = min(leftMax, rightMax) - arr[i] (if positive).

  2. Two-Pointer Logic:

    • Start with pointers at both ends: left = 0, right = n-1.

    • Track leftMax and rightMax as we move inward.

    • Process the side with smaller height first.

  3. Water Calculation:

    • If arr[left] < arr[right]: water at left is determined by leftMax.

      • Add max(0, leftMax - arr[left]) to result.

      • Update leftMax and move left pointer right.

    • Otherwise: water at right is determined by rightMax.

      • Add max(0, rightMax - arr[right]) to result.

      • Update rightMax and move right pointer left.

  4. Why This Works:

    • When processing left, we know there exists a taller bar on the right.

    • When processing right, we know there exists a taller bar on the left.

    • This guarantees correct water calculation without needing full left/right max arrays.

Mathematical Insight: The smaller of the two boundaries determines how much water can be trapped at any position.

πŸ“ Time and Auxiliary Space Complexity

  • Expected Time Complexity: O(n), where n is the size of the array. We make a single pass through the array using two pointers that move toward each other, processing each element exactly once.

  • Expected Auxiliary Space Complexity: O(1), as we only use constant extra space for pointer variables and tracking maximum heights from both sides.

πŸ§‘β€πŸ’» Code (C)

πŸ§‘β€πŸ’» Code (C++)

chevron-right⚑ View Alternative Approaches with Code and Analysishashtag

πŸ“Š 2️⃣ Prefix-Suffix Max Arrays

πŸ’‘ Algorithm Steps:

  1. Compute prefix max array storing maximum height to the left of each position.

  2. Compute suffix max array storing maximum height to the right of each position.

  3. For each position, water trapped = min(prefixMax, suffixMax) - height.

  4. Sum up water for all positions.

πŸ“ Complexity Analysis:

  • Time: ⏱️ O(n) - Three linear passes

  • Auxiliary Space: πŸ’Ύ O(n) - Two auxiliary arrays

βœ… Why This Approach?

  • Intuitive and easy to understand

  • Clear visualization of left and right maxima

  • Good for explaining the concept

πŸ“Š 3️⃣ Stack-Based Approach

πŸ’‘ Algorithm Steps:

  1. Use a stack to track indices of bars in decreasing height order.

  2. When a taller bar is found, calculate trapped water with previous bars.

  3. Water is trapped between current bar and bars in stack.

  4. Process each bar once with stack operations.

πŸ“ Complexity Analysis:

  • Time: ⏱️ O(n) - Each element pushed/popped once

  • Auxiliary Space: πŸ’Ύ O(n) - Stack storage

βœ… Why This Approach?

  • Calculates water layer by layer

  • Single pass with stack

  • Different perspective on the problem

πŸ“Š 4️⃣ Dynamic Programming Approach

πŸ’‘ Algorithm Steps:

  1. Use DP to store maximum heights efficiently.

  2. Build left max array in forward pass.

  3. Process right max and calculate water in single backward pass.

  4. Optimize space by reusing input array if modification allowed.

πŸ“ Complexity Analysis:

  • Time: ⏱️ O(n) - Two passes through array

  • Auxiliary Space: πŸ’Ύ O(n) - Single auxiliary array

βœ… Why This Approach?

  • Space optimized compared to prefix-suffix

  • Combines computation with water calculation

  • Good balance of clarity and efficiency

πŸ†š πŸ” Comparison of Approaches

πŸš€ Approach

⏱️ Time Complexity

πŸ’Ύ Space Complexity

βœ… Pros

⚠️ Cons

🎯 Two-Pointer

🟒 O(n)

🟒 O(1)

πŸš€ Optimal space, single pass

πŸ”§ Slightly complex logic

πŸ“Š Prefix-Suffix Arrays

🟒 O(n)

πŸ”΄ O(n)

πŸ“– Very intuitive

πŸ’Ύ Extra space required

πŸ”„ Stack-Based

🟒 O(n)

πŸ”΄ O(n)

🎯 Layer-by-layer calculation

πŸ”§ More complex implementation

πŸ“ˆ Dynamic Programming

🟒 O(n)

πŸ”΄ O(n)

⚑ Space optimized variant

πŸ’Ύ Still needs auxiliary space

πŸ† Best Choice Recommendation

🎯 Scenario

πŸŽ–οΈ Recommended Approach

πŸ”₯ Performance Rating

πŸ… Optimal performance needed

πŸ₯‡ Two-Pointer

β˜…β˜…β˜…β˜…β˜…

πŸ“– Learning/Understanding

πŸ₯ˆ Prefix-Suffix Arrays

β˜…β˜…β˜…β˜…β˜…

🎯 Different perspective

πŸ₯‰ Stack-Based

β˜…β˜…β˜…β˜…β˜†

πŸ’Ύ Space optimization

πŸ… Dynamic Programming

β˜…β˜…β˜…β˜…β˜†

β˜• Code (Java)

🐍 Code (Python)

🧠 Contribution and Support

For discussions, questions, or doubts related to this solution, feel free to connect on LinkedIn: πŸ“¬ Any Questions?arrow-up-right. Let's make this learning journey more collaborative!

⭐ If you find this helpful, please give this repository a star! ⭐


πŸ“Visitor Count

Visitor counter

Last updated