题目
给定 n n n 个非负整数表示每个宽度为 1 的柱子的高度图,计算按此排列的柱子,下雨之后能接多少雨水。
思路
- 方法一:双指针
- h e i g h t [ i ] height[i] height[i] 处所能接的雨水的最大高度为 m i n ( l e f t M a x , r i g h t M a x ) − h e i g h t [ i ] min(leftMax, rightMax) - height[i] min(leftMax,rightMax)−height[i],其中 l e f t M a x leftMax leftMax 为 i i i 左侧所有柱子的最大高度, r i g h t M a x rightMax rightMax 为右侧所有柱子的最大高度
-
l
e
f
t
M
a
x
,
r
i
g
h
t
M
a
x
leftMax, rightMax
leftMax,rightMax 的确定方法:
- 1)维护左右指针 p l , p r pl, pr pl,pr
- 2)更新 l e f t M a x / r i g h t M a x leftMax/rightMax leftMax/rightMax: l e f t M a x = m a x ( l e f t M a x , h e i g h t [ p l ] ) , r i g h t M a x 同理 leftMax = max(leftMax, height[pl]), rightMax同理 leftMax=max(leftMax,height[pl]),rightMax同理
- 3)更新 p l , p r pl, pr pl,pr:若 l e f t M a x < r i g h t M a x leftMax < rightMax leftMax<rightMax (说明 p l pl pl 左侧的最大值一定为 l e f t M a x leftMax leftMax,而右侧最大值大于等于 r i g h t M a x rightMax rightMax,此时 p l pl pl 处所能接的雨水的最大高度为 l e f t M a x − h e i g h t [ p l ] leftMax - height[pl] leftMax−height[pl]), p l + + pl++ pl++;否则 p r − − pr-- pr−−
- 方法二:单调栈
- 从左到右遍历 h e i g h t height height,若 h e i g h t [ i ] height[i] height[i] 一直减小,则一直入栈,直到 h e i g h t [ i ] height[i] height[i] 开始变大,此时停止入栈,开始计算水量
代码
class Solution {
public:
int trap(vector<int>& height) {
// int n = height.size();
// int pl = 0, pr = n-1;
// int left_max = height[pl], right_max = height[pr];
// int ret = 0;
// while(pl<pr){
// if(left_max < right_max){
// ret += left_max - height[pl];
// pl++;
// left_max = max(left_max, height[pl]);
// }
// else{
// ret += right_max - height[pr];
// pr--;
// right_max = max(right_max, height[pr]);
// }
// }
// return ret;
// 单调栈
int n = height.size();
stack<int> stk;
int ret=0;
for(int i = 0; i < n; i++){
while(!stk.empty() && height[i] > height[stk.top()]){
int top = stk.top();
stk.pop();
if(stk.empty())
break;
int left = stk.top();
ret += (min(height[left], height[i])-height[top]) * (i-left-1);
}
stk.push(i);
}
return ret;
}
};