42. 接雨水

作者: crj1998 | 来源:发表于2019-03-14 21:15 被阅读4次

原始题目

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

示例
上面是由数组 [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

分析

看到这个就会想到木桶效应,即所盛的水由短板决定。这里也是同理。

example
以上图为例分析一下过程,从左至右开始,位置1肯定是边界,也就是说位置1右边部分的水位绝对不可能高于此,所以我们可以从此开始遍历,如果后一位置的高度低于位置1,则假设这里的水位可以与1齐平,然后往后到位置6,一看,这里的高度高于位置1,也就是说,不管你6往后的洪水滔天,和位置1到5的水位无关,前面已经固定了。那么继续往后,由于不用考虑前面的,那么位置6相当于变为了位置1。但是到了位置8,此时最高为此位置,一直往后,到了位置12,由于位置12高度小于位置8,也就是说之前的假设的水位不可能真的达到,需要减去部分水位,那需要怎么减?这里处理就会麻烦,那么为什么1到6不用考虑减去呢?因为6高于1,假如12的位置也高于8,那么也不用考虑减去。所以根据短板效应,我们应该用短的那块高度做假设水位,即从高度低的向高度高的去移动。
但是如果从左至右依次遍历,除特殊情况,否则不可能始终从高度低的向高度高的走,所以不能从一端遍历,需要从两端同时遍历。

伪代码如下:

while(左端最高的位置在右端最高位置之前){
    if(左端最高的高度<右端最高的高度){
        左端位置向右移动,如果此位置小于最高则并记录下水位增加,否则此位置变为最高
    }
   else{
       右端位置向左移动,如果此位置小于最高则记录下水位增加,否则次位置变为最高
    }
}

Leetcode C++代码实现如下:

class Solution {
public:
    int trap(vector<int>& height) {
        int len = height.size();
        if(len==0) return 0;
        int ret=0;
        int lindex = 0, rindex = len-1;
        int left = height[lindex], right = height[rindex];
        while(lindex<rindex){
            if(left<right){
                if(height[++lindex]<left){ret += left-height[lindex];}
                else{left = height[lindex];}
            }
            else{
                if(height[--rindex]<right){ret += right-height[rindex];}
                else{right = height[rindex];}
            }
        }
        return ret;
    }
};

由于只遍历了一次,且存储空间和长度无关,则时间复杂度为O(n),空间复杂度为O(1),基本还是不错的。

相关文章

  • 42. 接雨水

  • 42. 接雨水

    ···class Solution {public int trap(int[] height) {int sum...

  • 42. 接雨水

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

  • 42. 接雨水

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

  • 42.接雨水

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

  • 42. 接雨水

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

  • 42. 接雨水

    题目描述 给定n个非负整数表示宽度为1的柱子高度,按此排序下雨后能接多少水。 示例: 解题思路 每个柱子可接的水量...

  • 42. 接雨水

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

  • 42. 接雨水

  • 42. 接雨水

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

网友评论

    本文标题:42. 接雨水

    本文链接:https://www.haomeiwen.com/subject/mnkhmqtx.html