Leetcode 42. Trapping Rain Water
Given n non-negative integers representing an elevation map where the width of each bar is 1, compute how much water it can trap after raining.
Constraints:
n == height.length
1 <= n <= 2 * 10^4
0 <= height[i] <= 10^5
Analysis:
This a classic question for interview.
If the water can be trapped at one position, then it requires there are two higher integers on its both side. So the question becomes how to decide the two sides.
We can use two vectors to record the largest integer so far: one is vector<int> left and the other is vector<int> right,
1. left[i] represents the largest elements so far from the left side;
2. right[i] represents the largest elements so far from the right side;
(Note: this is a very common trick used in dynamic programming.)
After having this information, we can do a third scan: for each element, just need to pick up the difference between nums[i] and the min(left[i], right[i]).
The time complexity is O(3N), and the space complexity is O(2N).
See the code below:
class Solution {
public:
int trap(vector<int>& height) {
int res = 0, n = height.size();
vector<int> left(n+1, 0), right(n+1, 0);
for(int i=0; i<n; ++i) {
left[i+1] = max(height[i], left[i]);
}
for(int i=n-1; i>=0; --i) {
right[i] = max(height[i], right[i+1]);
}
for(int i=0; i<n; ++i) {
res += max(min(left[i+1], right[i]) - height[i], 0);
}
return res;
}
};
class Solution {
public:
int trap(vector<int>& height) {
int res = 0, n = height.size(), id = 0, left = 0, right = n-1;
for(int i=1; i<n; ++i) {
if(height[i] > height[id]) id = i;
}
for(int i=1; i<id; ++i) {
if(height[i] > height[left]) left = i;
res += height[left] - height[i];
}
for(int i=n-1; i>id; --i) {
if(height[i] > height[right]) right = i;
res += height[right] - height[i];
}
return res;
}
};
class Solution {
public:
int trap(vector<int>& height) {
int res = 0, n = height.size();
stack<int> sk;
for(int i=0; i<n; ++i) {
while(sk.size() && height[sk.top()] < height[i]) {
auto t = sk.top();
sk.pop();
if(sk.size()) {
// height * width
res += (min(height[i], height[sk.top()]) - height[t]) * (i - sk.top() - 1);
}
}
sk.push(i);
}
return res;
}
};
Comments
Post a Comment