接雨水
参考链接 https://leetcode.com/problems/trapping-rain-water/solutions/1374608/c-java-python-maxleft-maxright-so-far-with-picture-o-1-space-clean-concise/
短板效应是短板决定整体的发挥,这里是左右边柱子低的决定储水量的多少
双指针结合短板效应 时间复杂度O(n) 空间复杂度O(1)
- 首先明确一点,计算的是每一列的需水量,遍历当前列时并不考虑其他列的需水量
- 根据maxLeft 和 maxRight的判断规则,maxLeft和maxRight 只会变大或者不变
- 根据短板效应,首先判断左右max中最小的板
- 如果maxLeft < maxRight 表示左侧最高柱子偏低,那么再判断height[left]和maxLeft
-
若 maxLeft > height[left],则当前列蓄水 maxLeft - height[left],当时我就比较纠结右侧最高与当前列(height[left]) 之间的柱子难道不会影响该列的结果吗?
-
根据捡漏的手绘图 无论中间的柱子 比height[left]小还是大都不会影响当前列的储水量
-
右边计算同理
-
- 之后就是水量的累加和left & right的遍历了
个人理解:理解计算单列储水量的逻辑是一个关键点,把这个搞明白,其他的左右指针遍历,水量累加都不是问题
class Solution { // 0 ms, faster than 100.00%
public int trap(int[] height) {
// 数组长度 <= 2 不能储水 直接返回
if (height.length <= 2) return 0;
// 初始化左右 maxLeft和maxRight
int n = height.length, maxLeft = height[0], maxRight = height[n-1];
// 初始化完maxLeft/Right,那么开始遍历的时候 从两个max中间开始遍历 1 ,n - 2
int left = 1, right = n - 2, ans = 0;
while (left <= right) {
if (maxLeft < maxRight) {
if (height[left] > maxLeft)
maxLeft = height[left];
else
ans += maxLeft - height[left];
left += 1;
} else {
if (height[right] > maxRight)
maxRight = height[right];
else
ans += maxRight - height[right];
right -= 1;
}
}
return ans;
}
}