Given n non-negative integers representing an elevation map where the width of each bar is 1, compute how much water it is able to trap after raining.
The above elevation map is represented by array [0,1,0,2,1,0,1,3,2,1,2,1]. In this case, 6 units of rain water (blue section) are being trapped. Thanks Marcos for contributing this image!
// Dynamic programming
int trap(vector<int>& height) { // time: O(n); space: O(n)
int res = 0, mx = 0, n = height.size();
vector<int> dp(n, 0);
// scan from left to right to record max left height
for (int i = 0; i < n; ++i) {
dp[i] = mx;
mx = max(mx, height[i]);
}
// reset mx to 0
mx = 0;
// scan from right to left to calculate res
for (int i = n - 1; i >= 0; --i) {
dp[i] = min(dp[i], mx); // record the minimum value between maxL and maxR
mx = max(mx, height[i]);
if (dp[i] > height[i]) res += dp[i] - height[i];
}
return res;
}
// Monotonic Stack
int trap(vector<int>& height) { // time: O(n); space: O(n)
int res = 0, i = 0, n = height.size();
stack<int> st;
while (i < n) {
if (st.empty() || height[i] <= height[st.top()]) st.push(i++);
else {
int t = st.top(); st.pop();
if (st.empty()) continue;
res += (min(height[st.top()], height[i]) - height[t]) * (i - st.top() - 1);
}
}
return res;
}