题目描述
给定 n 个非负整数表示每个宽度为 1 的柱子的高度图,计算按此排列的柱子,下雨之后能接多少雨水。
解题思路
从上图可以看出,位置i处能够存储的水是[0,i]的最大值和[i,n-1]的最大值中较小的那个与height[i]的差值。所以可以遍历两边数组得到位置i处的左侧和右侧的最大值,然后累加。
另一种思路,能够储水的一定的序列一定是先减再加的序列,那么利用栈进行处理,当当前元素小于栈中元素的时候,就入栈,大于则进行计算累加,直到栈顶元素大于当前元素。
实现代码
思路1:
class Solution{
public:
int trap(vector<int>& height){
int len=height;
vector<int> left_max(len,0),right_max(len,0);
left_max[0]=height[0];right_max[len-1]=height[len-1];
for(int i=1;i<len;i++)
left_max[i]=max(height[i],left_max[i-1]);
for(int i=len-2;i>=0;i--)
right_max[i]=max(height[i],right_max[i+1]);
int ans=0;
for(int i=1;i<len-1;i++)
ans+=min(left_max[i],right_max[i])-height[i];
}
return ans;
}
思路二
class Solution{
public:
int trap(vector<int>& height){
int ans=0,i=0;
stack<int> stk;
for(i=0;i<height.size();i++){
while(!stk.empty()&&height[i]>height[stk.top()]){
int top=stk.top();
stk.pop();
if(stk.empty())
break;
ans+=(min(height[i],height[stk.top()])-height[top])*(i-stk.top()-1);
}
stk.push(i);
}
return ans;
}
};