leecode42. 接雨水
题目描述:给n个高度不同的柱子(可为0),求能积水的容量
思路:如果俩个稍高的柱子中有一个比它们俩低的柱子,则能积水,积水的容量为最低的柱子高度-当前的柱子高度,观察样例,发现对于当前的点找到右边第一个比它高或者等于它的点,这个时候可以得出这一区间的容量,通过单调栈可以找到右边第一个比它高或者等于它的点,通过前缀和可以得出这一区间的高度和,然后进而得出这一区间的积水量.麻烦的是找到一个最高点后,后面没有比它小或者等于它的数,所以又从n为起点来一次,算它们之间区间的积水量
class Solution {
public:
int trap(vector<int>& height) {
int n=height.size();
int sums[n+5];
stack<int> sx;
vector<int> rg(n+5);
vector<int> lg(n+5);
for(int i=0;i<n;i++){
while(!sx.empty()&&height[sx.top()]<=height[i]){
rg[sx.top()]=i;
sx.pop();
}
sx.push(i);
if(i!=0)sums[i]=sums[i-1]+height[i];
else sums[i]=height[i];
}
int mx,ans=0;
for(int i=0;i<n;){
if(rg[i]==0){
mx=i;
break;
}
ans+=(rg[i]-i-1)*(height[i])-(sums[rg[i]-1]-sums[i]);
i=rg[i];
}
stack<int> sx2;
for(int i=n-1;i>=mx;i--){
while(!sx2.empty()&&height[sx2.top()]<=height[i]){
lg[sx2.top()]=i;
sx2.pop();
}
sx2.push(i);
}
for(int i=n-1;i>mx;){
ans+=(i-lg[i]-1)*(height[i])-(sums[i-1]-sums[lg[i]]);
i=lg[i];
}
return ans;
}
};
当然也有别的方法,比如我看到从行入手,使用单调栈解决问题,代码更简洁