42. 接雨水

42. 接雨水

给定 n 个非负整数表示每个宽度为 1 的柱子的高度图,计算按此排列的柱子,下雨之后能接多少雨水

在这里插入图片描述

上面是由数组 [0,1,0,2,1,0,1,3,2,1,2,1] 表示的高度图,在这种情况下,可以接 6 个单位的雨水(蓝色部分表示雨水)。 感谢 Marcos 贡献此图。

示例:

输入: [0,1,0,2,1,0,1,3,2,1,2,1]
输出: 6

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/trapping-rain-water
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
class Solution {
    public int trap(int[] height) {
        int ans=0;
        int n = height.length;
        if(n==0){return 0;}
        int[] l_max = new int[n];
        int[] r_max = new int[n];
        l_max[0] = height[0];
        r_max[n-1] = height[n-1];
        for (int i=1;i<n;i++){
            l_max[i] = Math.max(height[i],l_max[i-1]);
        }
        for(int i=n-2;i>=0;i--){
            r_max[i] = Math.max(height[i],r_max[i+1]);
        }
        for(int i=0;i<n-1;i++){
            ans+=Math.min(l_max[i],r_max[i]) - height[i];
        }
        return ans;
    }
}
我所需要知道的是每个位置的水容量是如何计算的,然后全部相加即可,通过观察
遍历整个数组时:
	i=0;V = 0;因为左边啥都没有
	i=1;V = 0;因为左边啥都没
	i=2;V= 1;因为左边有个1,右边最高为有个3,取小的;
	i=3;V = 0;左边最高(l_max)1,右边最高(r_max)位为3,取小的,
	此时就发现如果不包括自己的话,
	此时容量就会等于 min(1,3) - 2 = -1;因此计算最高或最低时应该处理包括自己本身,
	且这样做是正确的,比如当 i = 2时, 
	l_max = 1;r_max = 3; 当i = 9时,l_max = 3;r_max = 2;
	因此计算得到l_max或r_max时永远不会对计算结果造成影响,
	因为倘若你在这个位置低于左边最高,低于右边最高,那就不用管,
	若你在这个位置高于左边最高或高于右边最高,那你就盛不了任何水。

因此,我们需要做的是获取每个位置所能得到的左边最高以及右边最高,
	ans+= Math.min(l_max[i],r_max[i]) -height[i];
示例: [0,1,0,2,1,0,1,3,2,1,2,1] 
1.获取l_max数组,该数组表明了在每个位置所能获得的最大左侧高度
    l_max=[0,1,1,2,2,2,2,3,3,3,3,3],每次只看左边,不看右边
2.获取r_max数组,表明了在每个位置所能获得的最大右侧高度,此时算法和上面的获取算法一样,
    只是换个方向,从右到左,每次只看右边,不看左边
    r_max=[3,3,3,3,3,3,3,3,2,2,2,1]

示例: [0,1,0,2,1,0,1,3,2,1,2,1]
l_max=[0,1,1,2,2,2,2,3,3,3,3,3]
r_max=[3,3,3,3,3,3,3,3,2,2,2,1]
可以得到每个位置的容量 Math.min(l_max[i],r_max[i]) - height[i]
V=    [0,0,1,0,1,2,1,0,0,1,0,0]
在相加即可 1+1+2+1+1 = 6

你可能感兴趣的:(java,leetcode,算法)