30 Day Challenge Day 18 | Leetcode 42. Trapping Rain Water
题解
双指针
三次遍历,但不影响复杂度为O(n)。后面要进行改进。
class Solution {
public:
int trap(vector<int>& height) {
vector<int> max_left(height.size()+2, 0);
vector<int> max_right(height.size()+2, 0);
for(int i = 1; i < max_left.size()-1; i++) {
max_left[i] = max(max_left[i-1], height[i-1]);
}
for(int i = max_right.size()-2; i >= 1; i--) {
max_right[i] = max(max_right[i+1], height[i-1]);
}
int max_water = 0;
for(int i = 0; i < height.size(); i++) {
cout << max_left[i+1] << ", " << max_right[i+1] << ", "<< height[i] << endl;
max_water += max(min(max_left[i+1], max_right[i+1]) - height[i], 0);
}
return max_water;
}
};
一次遍历,左右双指针。
class Solution {
public:
int trap(vector<int>& height) {
int water = 0;
int l = 0, r = height.size()-1;
while(l < r) {
if(height[l] < height[r]) {
int bar = height[l];
l++;
while(l < r && height[l] < bar) {
water += bar - height[l];
l++;
}
} else {
int bar = height[r];
r--;
while(l < r && height[r] < bar) {
water += bar - height[r];
r--;
}
}
}
return water;
}
};
方法:Stack
参考官方答案,可以用Stack来做这道题。我用题干中的例子,手动运行了每一步,才大致理解。比上述的方法是相对难掌握一点。
主要思想就是通过Stack来保存左边的Bar,只要发现有凹槽形状出现就开始更新水量。
class Solution {
public:
int trap(vector<int>& height) {
int water = 0, cur = 0;
stack<int> st;
while(cur < height.size()) {
while(!st.empty() && height[cur] > height[st.top()]) {
int top = st.top();
st.pop();
if(st.empty()) break; // no left bar
int dist = cur - st.top() - 1;
water += dist * (min(height[st.top()], height[cur]) - height[top]);
}
st.push(cur++);
}
return water;
}
};