在leetcode刷题过程中,接雨水问题是比较经典的,特别是笔试面试喜欢出的问题。腾讯,Vivo等大厂都出现过,在这里通过自己学习,以及借鉴大佬的思路,对这道题进行整理。这道题涉及了动态规划
和单调栈
,包括动态规划的一个优化问题,以及单调栈的典型应用。
其它算法问题刷题总结可以参考:基础算法分类总结(持续更新中)。
文章目录
一、接雨水问题全面解析
1. 题目描述
leetcode题目链接:42. 接雨水
2. 解决方法
2.1 暴力 时间O(N^2) 空间O(1)
很明显每个柱子顶部可以储水的高度为:该柱子的左右两侧最大高度的较小者减去此柱子的高度。
因此我们只需要遍历每个柱子,累加每个柱子可以储水的高度即可。
class Solution {
public int trap(int[] height) {
int res = 0;
int n = height.length;
// 遍历每个柱子
for (int i = 1; i < n - 1; i++) {
int leftMax = 0, rightMax = 0;
// 计算当前柱子左侧的柱子中的最大高度
for (int j = 0; j <= i; j++) {
leftMax = Math.max(leftMax, height[j]);
}
// 计算当前柱子右侧的柱子中的最大高度
for (int j = i; j < n; j++) {
rightMax = Math.max(rightMax, height[j]);
}
// 结果中累加当前柱子顶部可以储水的高度,
// 即 当前柱子左右两边最大高度的较小者 - 当前柱子的高度。
res += Math.min(leftMax, rightMax) - height[i];
}
return res;
}
}
2.2 动态规划 时间O(N) 空间O(N)
在上述的暴力法中,对于每个柱子,我们都需要从两头重新遍历一遍求出左右两侧的最大高度&#x