LeetCode42. 接雨水

给定 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

思路,双指针法,找最大值max,表明最大值左边水面只可能由左到右慢慢升高,最大值右边水面只可能从右到左慢慢下降。

从最大值点把数组分成两部分,[begin,maxposition]闭区间,[maxposition,end]这个问题简化成一个问题,已知左/右边最高,求能接多少雨水?不失一般性,另右边最高,解左区间问题。单指针:

 

试想,这时,任何一点 i 的水面高度一定一定一定是从【0,i】之间的最大值,和峰值max之间的最小值(这句话好好理解!!),这样问题就很简单了,从0开始遍历,一直更新我的leftmaxnum,如果需要更新,则这个点一定不存水,如果不更新,一定存leftmaxnum-height[i]高度的水,求和即可。

 

右区间同左。

代码如下:

class Solution {
public:
    int trap(vector<int>& height) {
        if(height.size()==0) return 0;
        int maxn=0;
        auto maxloc=height.begin();
        for(auto a=height.begin();a!=height.end();a++){
            if(*a>maxn){
                maxn=*a;maxloc=a;
            }
        }
        auto leftpt = height.begin();
        int leftmaxnum=height[0];
        int sum=0;
        while(leftpt!=maxloc){
            if(*leftpt<leftmaxnum) sum+=(leftmaxnum-*leftpt);
            else{leftmaxnum=*leftpt;}
            leftpt++;
        }
        int rightmaxnum=0;
        auto rightpt = height.end()-1;
        while(rightpt!=maxloc){
            if(*rightpt<rightmaxnum) sum+=(rightmaxnum-*rightpt);
            else{rightmaxnum=*rightpt;}
            rightpt--;
        }
        return sum;
    }
};

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章