题目链接
英文链接:https://leetcode.com/problems/trapping-rain-water/
中文链接:https://leetcode-cn.com/problems/trapping-rain-water/
题目详述
给定 n 个非负整数表示每个宽度为 1 的柱子的高度图,计算按此排列的柱子,下雨之后能接多少雨水。
上面是由数组 [0,1,0,2,1,0,1,3,2,1,2,1] 表示的高度图,在这种情况下,可以接 6 个单位的雨水(蓝色部分表示雨水)。 感谢 Marcos 贡献此图。
示例:
1 | 输入: [0,1,0,2,1,0,1,3,2,1,2,1] |
题目详解
方法一:单调栈。
- 保持栈底到栈顶单调递减。
- 遍历数组,如果当前元素大于等于栈顶元素 ,弹出栈顶元素进行结算。
- 时间复杂度为
O(n)
,空间复杂度为O(n)
。
1 | public class LeetCode_00042 { |
方法二:双指针。
- 对于数组中的每个元素,它接的雨水量等于它左右两边最大高度的较小值减去当前高度的值。
- 对于每个元素,它左右两边最大高度可以提前算出来。
- 然后遍历数组,记录每个位置的雨水贡献量,累加即可。
- 时间复杂度为
O(n)
,空间复杂度为O(n)
。
1 | public class LeetCode_00042 { |
- 对上面的代码进行优化,可以不用找到当前位置左右两边的最大值再取较小值(短板),知道谁是短板后可以直接结算,因为接水量取决于短板,即便中间还有没有走过的位置,此时接水量已经确定了。
- 记短板高度为
s
,当前高度为c
,如果s > c
,则当前接水量为s - c
;否则为0
。 - 运用两个指针从两端往中间扫描,结算每个位置的雨水贡献量,累加即可。
- 时间复杂度为
O(n)
,空间复杂度为O(1)
。
1 | public class LeetCode_00042 { |
LeetCode11-盛最多水的容器 也是类似的思想,运用双指针进行扫描,不过结算的方式不同。