Trapping Rain Water

Problem

An array gives the heights of bars, each with the width 1. After rain, water is trapped between the bars. Print the total amount of trapped water.

Constraints

  • 1 <= n <= 10^5
  • 0 <= a[i] <= 10^5

Examples

Input

12
0 1 0 2 1 0 1 3 2 1 2 1

Output

6

Solutions

Best approachTime O(n)Space O(1)

Above a bar the water level is min(tallest bar on the left, tallest bar on the right) minus the bar height. With two pointers we move the lower side, because the other side is certainly at least as tall. This needs O(1) extra memory.

Same code works in Java810172125Basic features only, so nothing changes between versions.
/*
 * Problem : Process an array.
 * Input   : n, then n integers.
 * Output  : The trapped water.
 * Approach: Two pointers.
 * Time    : O(n)
 * Space   : O(1)
 * Java    : 8 or newer.
 */
import java.util.Scanner;

public class Main {
    // This method solves the task. It receives the input and returns the answer.
    static long solve(int[] a) {
        // Step 1: Two pointers from both ends. leftMax and rightMax = the tallest bar seen from each side.
        int left = 0;
        int right = a.length - 1;
        int leftMax = 0;
        int rightMax = 0;
        long water = 0;

        while (left < right) {
            // Step 2: Work on the lower side. Its water level is limited by its own side maximum.
            if (a[left] < a[right]) {
                leftMax = Math.max(leftMax, a[left]);
                water += leftMax - a[left];
                left++;
            } else {
                rightMax = Math.max(rightMax, a[right]);
                water += rightMax - a[right];
                right--;
            }
        }
        return water;
    }

    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int size = scanner.nextInt();
        int[] a = new int[size];
        for (int i = 0; i < size; i++) {
            a[i] = scanner.nextInt();
        }
        System.out.println(solve(a));
    }
}
Hints (2)
  1. What limits the water level above one bar?
  2. Which pointer should move?