单调栈的好题
class Solution {
public:
int trap(vector<int>& height) {
//找高低,单调栈!!柱子的宽度为1
//看每个柱子的上方能接多少雨水就行了
//找到比自己高的之后证明在自己和高的这段距离中的柱子一定都是小于自己和高的
stack<int> sta;
int res = 0;
for(int i = 0; i < height.size(); ++i){
while(!sta.empty() && height[sta.top()] < height[i]){
int top = sta.top();
sta.pop();
//如果弹出之后,左边没有可以一起接水的柱子了,直接退出循环
if(sta.empty()) break;
//height[top]是已经接了的雨水的高度
int gao = min(height[i],height[sta.top()])-height[top];
//弹出的栈顶只是个作为地基 的东西,所以真正的两边是当前柱子和新的栈顶
//说到底是对栈中的每个数进行操作,while循环内部每次求得是当前栈的栈顶可以存多少水!!是通过栈顶的左右第一个比自己高的柱子来接水的,所以要减去栈顶柱子自身的高度,因为自身是柱子不能接水。如果是4203这样的柱子,把0弹出后,也不用慌,因为3既然比2还大,那肯定比0也大,所以0这根柱子能接多少水已经处理过了,不用担心,所以当前柱子高度以下的我们不用管,早就处理过了
int kuan = i - sta.top()-1;
res += kuan*gao;
}
sta.push(i);
}
return res;
}
};
class Solution {
public:
int trap(vector<int>& height) {
//计算的是每一个柱子上面接多少水,用单调栈来做
stack<int> sta;
//stack中存的是下标,这样既可以直接取高度又可以算宽度
//如果当前柱子比栈顶柱子矮,就入栈,如果比栈顶柱子高,栈顶柱子下面还有柱子的情况下,栈顶柱子就可以接水了,因为两边都有比自己高的,碰到一个高的,要弹到栈顶比自己高为止
int res = 0;
for(int i = 0;i < height.size(); ++i){
//如果比栈顶高,但是要先判断栈是否为空,不然一开始会出错
while(!sta.empty() && height[i] >= height[sta.top()]){
int diji = sta.top();
sta.pop();
if(sta.empty()) break;
int kuan = i - sta.top()-1;
int gao = min(height[sta.top()],height[i])-height[diji];
res += kuan*gao;
}
sta.push(i);
}
return res;
}
};