🧠
Prefix and Suffix Max Arrays
💡 This approach precomputes maximum heights to the left and right for each bar to avoid repeated scanning, improving efficiency.
Intuition
If we know the tallest bar to the left and right of each bar, we can directly compute trapped water without nested loops.
Algorithm
- Create an array left_max where left_max[i] is the tallest bar from start to i.
- Create an array right_max where right_max[i] is the tallest bar from end to i.
- For each bar, trapped water = max(0, min(left_max[i], right_max[i]) - height[i]).
- Sum trapped water for all bars.
💡 Precomputing max arrays removes the need for nested loops, making the solution more efficient and easier to understand.
def trap(height):
n = len(height)
if n == 0:
return 0
left_max = [0] * n
right_max = [0] * n
left_max[0] = height[0]
for i in range(1, n):
left_max[i] = max(left_max[i-1], height[i])
right_max[n-1] = height[n-1]
for i in range(n-2, -1, -1):
right_max[i] = max(right_max[i+1], height[i])
water = 0
for i in range(n):
water += max(0, min(left_max[i], right_max[i]) - height[i])
return water
# Driver code
if __name__ == '__main__':
print(trap([0,1,0,2,1,0,1,3,2,1,2,1])) # Output: 6
Line Notes
if n == 0:Handle empty input edge case to avoid errors.
left_max = [0] * nInitialize array to store max heights from left.
left_max[0] = height[0]Set first element as starting max from left.
for i in range(1, n)Fill left_max by comparing current height with previous max.
right_max = [0] * nInitialize array to store max heights from right.
right_max[n-1] = height[n-1]Set last element as starting max from right.
for i in range(n-2, -1, -1)Fill right_max by comparing current height with next max.
water += max(0, min(left_max[i], right_max[i]) - height[i])Calculate trapped water at each bar using precomputed maxes, avoid negative values.
public class Solution {
public static int trap(int[] height) {
int n = height.length;
if (n == 0) return 0;
int[] left_max = new int[n];
int[] right_max = new int[n];
left_max[0] = height[0];
for (int i = 1; i < n; i++) {
left_max[i] = Math.max(left_max[i-1], height[i]);
}
right_max[n-1] = height[n-1];
for (int i = n-2; i >= 0; i--) {
right_max[i] = Math.max(right_max[i+1], height[i]);
}
int water = 0;
for (int i = 0; i < n; i++) {
water += Math.max(0, Math.min(left_max[i], right_max[i]) - height[i]);
}
return water;
}
public static void main(String[] args) {
int[] height = {0,1,0,2,1,0,1,3,2,1,2,1};
System.out.println(trap(height)); // Output: 6
}
}
Line Notes
if (n == 0) return 0;Handle empty input to avoid errors.
int[] left_max = new int[n];Create array to store max heights from left.
left_max[0] = height[0];Initialize first element for left max array.
for (int i = 1; i < n; i++)Fill left_max by comparing current height with previous max.
int[] right_max = new int[n];Create array to store max heights from right.
right_max[n-1] = height[n-1];Initialize last element for right max array.
for (int i = n-2; i >= 0; i--)Fill right_max by comparing current height with next max.
water += Math.max(0, Math.min(left_max[i], right_max[i]) - height[i]);Calculate trapped water at each bar using precomputed maxes, avoid negative values.
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int trap(vector<int>& height) {
int n = height.size();
if (n == 0) return 0;
vector<int> left_max(n), right_max(n);
left_max[0] = height[0];
for (int i = 1; i < n; i++) {
left_max[i] = max(left_max[i-1], height[i]);
}
right_max[n-1] = height[n-1];
for (int i = n-2; i >= 0; i--) {
right_max[i] = max(right_max[i+1], height[i]);
}
int water = 0;
for (int i = 0; i < n; i++) {
water += max(0, min(left_max[i], right_max[i]) - height[i]);
}
return water;
}
int main() {
vector<int> height = {0,1,0,2,1,0,1,3,2,1,2,1};
cout << trap(height) << endl; // Output: 6
return 0;
}
Line Notes
if (n == 0) return 0;Handle empty input to avoid runtime errors.
vector<int> left_max(n), right_max(n);Create arrays to store max heights from left and right.
left_max[0] = height[0];Initialize first element of left max array.
for (int i = 1; i < n; i++)Fill left_max by comparing current height with previous max.
right_max[n-1] = height[n-1];Initialize last element of right max array.
for (int i = n-2; i >= 0; i--)Fill right_max by comparing current height with next max.
water += max(0, min(left_max[i], right_max[i]) - height[i]);Calculate trapped water at each bar using precomputed maxes, avoid negative values.
function trap(height) {
const n = height.length;
if (n === 0) return 0;
const left_max = new Array(n).fill(0);
const right_max = new Array(n).fill(0);
left_max[0] = height[0];
for (let i = 1; i < n; i++) {
left_max[i] = Math.max(left_max[i-1], height[i]);
}
right_max[n-1] = height[n-1];
for (let i = n-2; i >= 0; i--) {
right_max[i] = Math.max(right_max[i+1], height[i]);
}
let water = 0;
for (let i = 0; i < n; i++) {
water += Math.max(0, Math.min(left_max[i], right_max[i]) - height[i]);
}
return water;
}
// Test
console.log(trap([0,1,0,2,1,0,1,3,2,1,2,1])); // Output: 6
Line Notes
if (n === 0) return 0;Handle empty input to prevent errors.
const left_max = new Array(n).fill(0);Initialize array to store max heights from left.
left_max[0] = height[0];Set first element as starting max from left.
for (let i = 1; i < n; i++)Fill left_max by comparing current height with previous max.
const right_max = new Array(n).fill(0);Initialize array to store max heights from right.
right_max[n-1] = height[n-1];Set last element as starting max from right.
for (let i = n-2; i >= 0; i--)Fill right_max by comparing current height with next max.
water += Math.max(0, Math.min(left_max[i], right_max[i]) - height[i]);Calculate trapped water at each bar using precomputed maxes, avoid negative values.
We traverse the array multiple times but each traversal is linear, and we use extra arrays of size n.
💡 For n=20 bars, this means about 60 operations plus extra memory for two arrays of size 20.
Interview Verdict: Accepted; efficient for large inputs but uses extra space.
This approach is a common interview solution that balances clarity and efficiency.