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;
    }
};

 

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