给定 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
双指针
class Solution {
public:
int trap(vector<int>& h) {
//有凹槽,才会接水。
//双指针。
int rmax = 0,lmax =0;
int i = 0,j = h.size()-1;
int sum = 0;
while(i < j){
lmax = max(lmax,h[i]); // 每次比较是 比较左边的
rmax = max(rmax,h[j]); // 每次判断的是右边的
if(lmax < rmax){ // 目标值的左边最大值 小于 右边最大值。装水取决于短板
sum += lmax - h[i];
i++;
}
else{
sum += rmax - h[j];
j--;
}
}
return sum;
}
};
单调栈
class Solution {
public:
int trap(vector<int>& h) {
//单调栈。找到目标值的左边第一个比自己大的,和 右边第一个比自己大的
//取两个大的 较小者才决定装多少水
int sum = 0;
stack<int>st;
st.push(0);
for(int i = 1;i < h.size();i++){
if(h[i] < h[st.top()]) st.push(i);
else if(h[i] == h[st.top()]) st.push(i);
else {
while(!st.empty() && h[i] > h[st.top()]){
int mid = h[st.top()];//目标值
st.pop();
if(!st.empty()){
int right = h[i];
int left = h[st.top()];
int hh = min(right, left) - mid;
int w = i-st.top()-1;
sum += hh*w;
}
}
st.push(i);
}
}
return sum;
}
};