原題連接配接:https://leetcode-cn.com/problems/trapping-rain-water/
解題思路:
- 将每個柱子都當做一個水桶,單獨計算其轉水量,再加和即可得到結果。
- 使用兩個指針分别指向左右桶壁。
- 假設目前要計算第i個水桶的轉水量,其實我們隻關心它的左右桶壁中較低的一個。
- 第i個水桶的指針隻要選取從左右桶壁中較小的一個,就保證了目前的桶壁高度必然比另一側的所有高度都小,即可用來計算目前桶的轉水量。
- 完成計算後,把目前桶的指針向内移動,判斷并計算下一個桶的轉水量即可。
/**
* @param {number[]} height
* @return {number}
*/
var trap = function (height) {
let result = 0; // 存儲結果
// 目前桶桶壁高度
let leftMax = height[0]; // 目前桶左側最高桶壁
let rightMax = height[height.length - 1]; // 目前桶右側最高桶壁
// 目前桶桶壁索引,同時也是用于計算目前裝水數量的水桶索引
let left = 1; // 目前桶左側最高桶壁的索引
let right = height.length - 2; // 目前桶右側最高桶壁的索引
// 兩個指針向内推進,計算裝水總量
// 兩個指針相等時也要計算,否則會遺漏一個水桶
while (left <= right) {
// 對于單個水桶來說,它其實隻關心最低的桶壁是哪個
// 而已知的左右桶壁中較小的那個,必然是目前桶的最小桶壁
// 同時較小的指針指向的就是目前要計算的桶,直接計算目前桶的可裝水量即可
// 完成計算後将目前指針向内移動一步,目前所使用的桶壁高度,需要同時更新
if (leftMax < rightMax) {
// 在移動之前先更新目前桶壁的高度
// 如果目前桶底高度大于桶壁,計算的轉水量會為0
leftMax = Math.max(height[left], leftMax);
// 計算目前轉水量之後,将指針向内移動一位
result += leftMax - height[left++];
} else {
rightMax = Math.max(height[right], rightMax);
result += rightMax - height[right--];
}
}
return result;
};