LeetCode 热题100:42.接雨水
这道题也可以用双指针
情景:如果有一个木桶,做桶高为left,右桶高为right,桶的底座厚height,则水可以接的面积为:
Volume = min(left, right) - height,即总是以桶最短的边减去底座装满水。
解题思路:
- 双指针从桶的最左边[0]和最右边[length-1]开始
- 记录当前桶的左边桶高为height[left]和height[right],将left_max = height[left]和right_max = height[right]此时无法接水。
- 由于总是以桶最短的边减去底座装满水:
- 如果left_max > right_max:移动短桶边(也就是right_max一边)使right--。
- 移动后,若height[right] 比 right_max 小,则该格接水公式为:V = min(left, right) - height[right]。将每一个格子接水累加,得到最终答案。
- 移动后,若height[right] 比 right_max大,则将right_max更新为当前桶高。
- 判断左右边界桶高,重复1-2-3的步骤,左右同理。
关键理解点1:不论如何,right指针和left指针最终会汇聚到height最高的一列,也就是Math.max(...height)
关键理解点2:每一格为最小单位,它总是以桶最短的边减去底座高度装水。
结合代码更好理解,代码如下:
var trap = function (height) {let ans = 0;let left = 0;let right = height.length - 1;let left_max = 0;let right_max = 0;while (left < right) {left_max = Math.max(height[left], left_max);right_max = Math.max(height[right], right_max);if (left_max < right_max) {ans = ans + left_max - height[left];left++;} else {ans = ans + right_max - height[right];right--;}}return ans;
};