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
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.
/*
* 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)
- What limits the water level above one bar?
- Which pointer should move?