leetcode42-接雨水
leetcode 42
思路
本题使用 单调栈
来计算每个位置能够接住的雨水量
理解问题
题目要求计算一系列柱子之间可以接住的雨水量。输入是一个数组,每个元素代表柱子的高度。输出是一个整数,表示能够接住的水量。
找到边界条件
- 什么情况下可以接住雨水,水量的计算依赖于柱子两边的高度,即左边界和右边界的高度
- 确定两边高度后,能够接住的水量 由
较低的边界
决定
设想解决方案
考虑到要计算每一段之间的水量,可以考虑以下几种方案:
- 暴力法:对于每一个柱子,遍历找到它左边和右边的最高柱子的高度,计算水量。这个方案复杂度较高(O(n2)),在处理大数据时会变得非常慢
- 预处理法:可以使用两个数组存储左边和右边每个柱子的最大高度。这种方法的复杂度为 O(n) 时间和 O(n) 空间。但这并不算最优
优化思路
我们可以利用堆栈的应用,来高效的找到边界并计算水量,单调栈就可以巧妙解决此题
- 单调栈:栈中的柱子会按高度
递增
。每当遇到比栈顶高的柱子时,就可以弹出栈顶元素
计算水量
实现细节
从左到右遍历数组height,每当遇到更高的柱子时,就开始计算水量
- 弹出栈顶元素,计算当前柱子与新栈顶之间的水量
- 使用 Math.min 函数确定雨水高度,并计算当前的水量
实现
var trap = function (height) {const len = height.length;// 单调栈const stack = [0];let result = 0;for (let i = 1; i < len; i++) {while (stack.length && height[i] > height[stack[stack.length - 1]]) {const index = stack.pop();if (stack.length) {const diffHeight = Math.min(height[i], height[stack[stack.length - 1]]) - height[index];result += diffHeight * (i - stack[stack.length - 1] - 1)}}stack.push(i);}return result;
};