给定 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 个单位的雨水(蓝色部分表示雨水)。
方法一:双指针
- 对撞指针
- leftMax表示在从开始到末尾遍历时所遇到的最大值,rightMax同理
function getWaters(nums){
let waters = 0;
let l =0, r= nums.length -1;
let leftMax = 0, rightMax = 0;
while(l < r){
if(nums[l] < nums[r]){
if(nums[l] >= leftMax){
leftMax = nums[l]
}else{
waters += nums[l] - leftMax
}
l++
}else{
if(nums[r] >= rightMax){
rightMax = nums[r]
}else{
waters += nums[r] - rightMax
}
r--
}
}
return waters
}
方法二:栈
维护一个递减栈
function getWaters(nums){
let waters = 0;
let stack = []; //用来存放遍历过程中遇到的最大值的索引
for(let i=0; i<nums.length; i++){
let item = nums[i]
while(item >= nums[stack[stack.length - 1]]){
let perMax = stack.pop();
if(!stack.length) break;
let w = i - stack[stack.length - 1] - 1;
let h = Math.min( item , nums[stack[stack.length - 1]] ) - nums[perMax]
waters += w * h;
}
stack.push(i)
}
return waters
}