难度困难2783
给定 n
个非负整数表示每个宽度为 1
的柱子的高度图,计算按此排列的柱子,下雨之后能接多少雨水。
示例 1:
输入:height = [0,1,0,2,1,0,1,3,2,1,2,1] 输出:6 解释:上面是由数组 [0,1,0,2,1,0,1,3,2,1,2,1] 表示的高度图,在这种情况下,可以接 6 个单位的雨水(蓝色部分表示雨水)。
示例 2:
输入:height = [4,2,0,3,2,5] 输出:9
提示:
n == height.length
1 <= n <= 2 * 104
0 <= height[i] <= 105
//1:预先处理一下该结点的左右边界最大值
class Solution {
public:
bool find132pattern(vector<int>& nums) {
//从右向左维护一个单调递减的单调栈
//i j k
//k就是维护的2
int k=INT_MIN;
stack<int>stk;
//k不为零就代表 右边一定存在一个递减的对 与
for(int i=nums.size()-1;i>=0;i--)
{
if(nums[i]<k)
return true;
while(!stk.empty()&&nums[i]>stk.top())
{
k=max(k,stk.top());
stk.pop(); //维护k就是132 中的2 而3已经入栈
}
stk.push(nums[i]);
}
return false;
}
};
//2:单调栈 维护一个递减的栈 栈顶就是低洼 出现比低洼大的 那么就能收集雨水了
//记录好低洼 然后左边界就是下一个低洼了
class Solution {
public:
int trap(vector<int>& height) {
//利用单调栈维护一个递减单调栈
//从左向右进行判断 能够形成低洼的话 应该是有左右边界 并且有一个低洼
//右边界是遍历数组得到的 所以此前stack中应该存储左边界和低洼
stack<int>stk;
int fins=0;
int n=height.size();
for(int i=0;i<n;i++)
{
///栈内存放的是每一个柱子的下标
while(!stk.empty()&&height[i]>height[stk.top()])
{
int low=stk.top(); //低洼的高度
stk.pop();
//出栈后 目前栈顶的元素就是左边界
if(stk.empty())
{
break;
}
int left=stk.top(); //此时栈顶就是左边界的下标
int diatance=i-left-1; //宽度
int hei=min(height[left],height[i])-height[low]; //左右边界的最小值减去low
fins+=diatance*hei;
}
stk.push(i);
}
return fins;
}
};