题目描述:
给定 n 个非负整数表示每个宽度为 1 的柱子的高度图,计算按此排列的柱子,下雨之后能接多少雨水。
上面是由数组 [0,1,0,2,1,0,1,3,2,1,2,1] 表示的高度图,在这种情况下,可以接 6 个单位的雨水(蓝色部分表示雨水)。 感谢 Marcos 贡献此图。
示例:
输入: [0,1,0,2,1,0,1,3,2,1,2,1]
输出: 6
解题思路:
看了一下相关话题:栈、数组、双指针就有思路了~
先从i = 0扫一遍,某个柱子 i 可能是最高的或者不是最高的。
1、假设它不是最后的,后面有比它高的,那么在遇到比它高的柱子之前,i 柱子后面的雨水都是堆积到它的高度。记录下 i 柱子的高度 firstHeight = height[i],并且把 i 柱子压栈,一直扫下去并且压栈。当遇到比 firstHeight 高的柱子时,把堆栈全部弹出来:
total += firstHeight - stack.top()
2、假设它是最高的,那么边扫边压栈到最后,再把堆栈弹出来,把遇到的第一个柱子当成 firstHeigh,后面的柱子如果大于 firstHeigh ,则更新。这样子后面的雨水也都是只能堆积到 firstHeigh 的高度:
total += firstHeight - stack.top()
代码:
执行用时: 8 ms, 在Trapping Rain Water的C++提交中击败了 97.62% 的用户
class Solution {
public:
int trap(vector<int>& height) {
stack<int> myStack;
int firstHeight = INT_MAX, total = 0;
for(int i=0; i<height.size(); i++) {
if(height[i] == 0) {
if(!myStack.empty())
myStack.push(0);
} else {
if(height[i] >= firstHeight) {
while(!myStack.empty()) {
total += firstHeight - myStack.top();
myStack.pop();
}
myStack.push(height[i]);
firstHeight = height[i];
} else {
if(myStack.empty())
firstHeight = height[i];
myStack.push(height[i]);
}
}
}
if(!myStack.empty())
firstHeight = myStack.top();
while(!myStack.empty()) {
if(myStack.top() > firstHeight)
firstHeight = myStack.top();
else
total += firstHeight - myStack.top();
myStack.pop();
}
return total;
}
};