LeetCode:42. 接雨水
/**
* 整体解题思路如下:
* 1. 首先,在高度数组中找到最高柱子的索引。因为最高柱子会把数组分为左右两部分,
* 后续分别从左右两侧向最高柱子进行遍历计算雨水量。
* 2. 从左到右遍历到最高柱子的左边部分:
* - 维护一个变量 last 来记录当前遍历区间内的最大高度的柱子索引。
* - 当当前柱子高度大于等于 last 位置的柱子高度时,更新 last 为当前索引。
* - 当当前柱子高度小于 last 位置的柱子高度时,说明可以接住雨水,
* 能接住的雨水量为 last 位置柱子高度与当前柱子高度的差值,将其累加到结果变量 ans 中。
* 3. 从右到左遍历到最高柱子的右边部分:
* - 同样维护一个变量 last 记录当前遍历区间内的最大高度的柱子索引。
* - 若当前柱子高度大于等于 last 位置的柱子高度,更新 last 为当前索引。
* - 若当前柱子高度小于 last 位置的柱子高度,将 last 位置柱子高度与当前柱子高度的差值累加到 ans 中。
* 4. 最终,ans 中存储的就是能接住的雨水总量。
*
* 算法时间复杂度分析:
* - 首先需要遍历一次数组来找到最高柱子的索引,时间复杂度为 O(n),其中 n 是数组的长度。
* - 接着从左到右和从右到左分别遍历数组到最高柱子的位置,每个方向的遍历时间复杂度也是 O(n)。
* - 总体来看,整个算法只对数组进行了常数次遍历,因此时间复杂度为 O(n)。
*
* 算法空间复杂度分析:
* 只使用了常数级的额外变量(如 maxIndex、ans、last 等),不随数组长度 n 的变化而变化,
* 所以空间复杂度为 O(1)。
*/
class Solution {
public int trap(int[] height) {
int n = height.length;
// 用于记录高度数组中最高柱子的索引
int maxIndex = 0;
// 遍历高度数组,找到最高柱子的索引
for (int i = 0; i < n; i++) {
if (height[maxIndex] < height[i]) {
maxIndex = i;
}
}
// 用于存储能接住的雨水总量,初始化为 0
int ans = 0;
// 用于记录当前区间内的最大高度的索引,初始化为 0
int last = 0;
// 从左到右遍历到最高柱子的左边部分
for (int i = 0; i < maxIndex; i++) {
// 如果当前柱子高度大于等于当前区间内的最大高度
if (height[i] >= height[last]) {
// 更新当前区间内的最大高度的索引
last = i;
} else {
// 否则,能接住的雨水量为当前区间内最大高度与当前柱子高度的差值
ans += height[last] - height[i];
}
}
// 更新 last 为数组最右边的索引,准备从右往左遍历
last = n - 1;
// 从右到左遍历到最高柱子的右边部分
for (int i = n - 1; i > maxIndex; i--) {
// 如果当前柱子高度大于等于当前区间内的最大高度
if (height[i] >= height[last]) {
// 更新当前区间内的最大高度的索引
last = i;
} else {
// 否则,能接住的雨水量为当前区间内最大高度与当前柱子高度的差值
ans += height[last] - height[i];
}
}
return ans;
}
}
坚冰还盖着北海的时候,我看到了怒放的梅花。

浙公网安备 33010602011771号