题目
给定 n
个非负整数表示每个宽度为 1
的柱子的高度图,计算按此排列的柱子,下雨之后能接多少雨水。
示例 1:
输入:height = [0,1,0,2,1,0,1,3,2,1,2,1] 输出:6 解释:上面是由数组 [0,1,0,2,1,0,1,3,2,1,2,1] 表示的高度图,在这种情况下,可以接 6 个单位的雨水(蓝色部分表示雨水)。
示例 2:
输入:height = [4,2,0,3,2,5] 输出:9
思考
其实和之前的双指针有异曲同工之妙。只要两边比中间高就可以?TAT感觉脑子木木的,今天就先按照官方给的题解写一遍学习吧,困难难度好难想...就看看软件思维的不暴力算法
动态规划
使用动态规划的方法,可以在 O(n) 的时间内预处理得到每个位置两边的最大高度,然后两边对比。动态规划做法可以由下图体现。
class Solution {
public int trap(int[] height) {
int n = height.length;
if (n == 0) {
return 0;
}
int[] leftMax = new int[n];
leftMax[0] = height[0];
for (int i = 1; i < n; ++i) {
leftMax[i] = Math.max(leftMax[i - 1], height[i]);
}
int[] rightMax = new int[n];
rightMax[n - 1] = height[n - 1];
for (int i = n - 2; i >= 0; --i) {
rightMax[i] = Math.max(rightMax[i + 1], height[i]);
}
int ans = 0;
for (int i = 0; i < n; ++i) {
ans += Math.min(leftMax[i], rightMax[i]) - height[i];
}
return ans;
}
}
作者:力扣官方题解
链接:https://leetcode.cn/problems/trapping-rain-water/solutions/692342/jie-yu-shui-by-leetcode-solution-tuvc/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
双指针
left从左向右遍历,right从右向左遍历;
则对left来说,leftMax一定准确,rightMax不一定准确,因为区间(left, right)的值还没有遍历,但是left的rightMax一定 >= right的rightMax,所以只要leftMax < rightMax时,我们不关系left的rightMax是多少了,因为它肯定比leftMax大,我们可以直接计算出left的存水量leftMax - nums[left];
对right来说,rightMax一定准确,leftMax不一定准确,因为区间(left, right)的值还没有遍历,但是right的leftMax一定 >= left的leftMax,所以只要leftMax >= rightMax时,我们不关系right的leftMax是多少了,因为它肯定比rightMax大,我们可以直接计算出right的存水量rightMax - nums[right];
class Solution {
public int trap(int[] height) {
int ans = 0;
int left = 0, right = height.length - 1;
int leftMax = 0, rightMax = 0;
while (left < right) {
leftMax = Math.max(leftMax, height[left]);
rightMax = Math.max(rightMax, height[right]);
if (height[left] < height[right]) {
ans += leftMax - height[left];
++left;
} else {
ans += rightMax - height[right];
--right;
}
}
return ans;
}
}
作者:力扣官方题解
链接:https://leetcode.cn/problems/trapping-rain-water/solutions/692342/jie-yu-shui-by-leetcode-solution-tuvc/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。