题目链接;
给定 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 个单位的雨水(蓝色部分表示雨水)。
题解:
先尝试用栈的方式解决,维护一个单调递减的序列。这样做的目的是,当发现有一个高度,比栈顶大,那么就可以从栈内取出两个元素,组成一个低洼地区,将所有低洼地区加起来,就是可以接雨水的量,下面边解题边注释。
function trap(height) {
/*
* 虽然这个栈保存的是索引,
* 但内容一定是单调递减的
* 因为一旦有发现比现在值更低的,就会不断的组成低洼,并pop掉
*/
const stack = [];
const len = height.length;
let i = 0, ans = 0;
while(i < len) {
const curr = height[i];
// 当遇到更高的高度,说明可以组成一个低洼地区
while(stack.length && curr > height[stack[stack.length - 1]]) {
const mid = stack.pop();
if (!stack.length) {
// 左边无法围住的话,无法形成低洼,直接break即可
break;
}
// 这里不直接pop掉的原因是:
// 因为这个left是一个比mid更高的高度
// 说不定之后也会有一个相同高度,或者更高的,与left组成一个低洼地区
// 所以不能直接pop掉
const left = stack[stack.length -1];
// 当前低洼地区的高度,取决于左右两遍更低的那个高度
const h = Math.min(curr , height[left]) - height[mid];
const w = i - left - 1;
ans += w * h;
}
stack.push(i++);
}
return ans;
}