42. 接雨水(Trapping rain water)
题目描述
LeetCode.cn地址:https://leetcode-cn.com/problems/trapping-rain-water/
LeetCode地址:https://leetcode.com/problems/trapping-rain-water/
思路
首先求出最大值的索引,设为i1,然后向左遍历,求出左边范围内的最大值,记索引为i2,以i2和i1对应值之间为容器,雨水可以存储在此中,多余的雨水会流向左右的下方。
记容积为height[i2] * (i1-i2),减去中间凸出的值,即为雨水的量。然后记i1=i2,再继续向左遍历。直到i1=0为止。
同理向右遍历。
模型解释
如上图所示,把最大值的索引记为i1,左边范围内的最大值索引为i2,可见,i2~i1之间储存了雨水。
那么这一部分雨水是多少呢?
让我们把图更精确一点:雨水的体积就等于
height[i2]*(i1-i2)
减去i2和i1之间黑色块的体积。
这一段的代码:
int i2 = max(height, 0, i1);
int a = height[i1], b = height[i2];
int tmp = b*(i1-i2);
for(int j = i2;j<i1;j++){
tmp -= height[j];
}
res += tmp;
之后令i1等于i2,向左重复以上步骤。
当然右边部分的也处理相同。
代码
class Solution {
public int trap(int[] height) {
int res = 0;
int left = 0, right = height.length;
if(height == null || height.length==0||height.length==1) return res;
int i1 = max(height, 0, right);
while(i1>0){
int i2 = max(height, 0, i1);
int a = height[i1], b = height[i2];
int tmp = b*(i1-i2);
for(int j = i2;j<i1;j++){
tmp -= height[j];
}
res += tmp;
i1 = i2;
}
i1 = max(height, 0, right);
while(i1<height.length-1){
int i2 = max(height, i1+1, right);
int a = height[i1], b = height[i2];
int tmp = b*(i2-i1);
for(int j = i2;j>i1;j--){
tmp -= height[j];
}
res+=tmp;
i1 = i2;
}
return res;
}
public static int max(int[] nums, int l, int r){
int tmp = nums[l];
int res = l;
for(int i=l;i<r;i++){
if(nums[i]>tmp){
tmp = nums[i];
res = i;
}
}
return res;
}
}
更多LeetCode题解在 https://github.com/FuGaZn/LeetCode
欢迎过来给个Star~
您的肯定是我更新的动力。