若柱子高度单调递减,无法接到雨水
直到存在一个高度大于当前容器内柱子高度的柱子,才可形成水槽
该问题可以转换为寻找右边第一个比某个数大的数
解题思路:
- 维护一个单调递减的栈,栈存储的是heights数组的下标
- 若遇到一个破坏栈单调递减的元素(入栈元素比栈顶元素大),将栈顶元素记录为pre并出栈,
(这里的pre是水槽右侧柱子的前驱元素,目的是为了后续计算水槽中间的有效水量)
- 之后检查栈是否为空 (避免出现没有left(左边界) 例如 0 2这种情况)
- 若不为空,说明是一个完整的水槽,此时计算高度和宽度
(宽度-1是为了避免左右边界连续出现导致计算错误)
- 累加水量,输出答案
#include <bits/stdc++.h>
using namespace std;
const int N = 1e5+10;
int stk[N],top=0,heights[N];
int main(){
int n,ans=0;
cin >> n;
for (int i = 0;i< n ;i++){
cin >> heights[i];
while(top!=0 && heights[i] > heights[stk[top]]){
int pre = stk[top--];
if (top==0){
break;
}
int left = stk[top];
int width = i - left -1;
int height = (min(heights[left],heights[i])-heights[pre]);
ans += (width*height);
}
stk[++top]= i;
}
cout << ans << '\n';
return 0;
}