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

 

解答:

拿的官方题解的图:

保存每个下标的left、right值。取小的加起来就是总的雨水量。

 

 双指针:(好难想)

class Solution {
public:
    int trap(vector<int>& height) {
        int n=height.size();
        int le=0,ri=n-1,le_mx=0,ri_mx=n-1,res=0;
        while(le<ri){
            if(height[le]<height[ri]){
                if(height[le]>height[le_mx]){
                    le_mx=le;
                }
                else{
                    res+=height[le_mx]-height[le];
                }
                ++le;
            }
            else{//height[le]>=height[ri],那么height[le_max]>=height[le]>=height[ri],所以:
            //height[le_mx]>height[ri]
                if(height[ri]>height[ri_mx]){
                    ri_mx=ri;
                }
                else{
                    res+=height[ri_mx]-height[ri];
                }
                --ri;
            }
        }
        return res;
    }
};

 

 

class Solution {
public:
    int trap(vector<int>& height)
{
    if(height.size()==0)
        return 0;
    int ans = 0;
    int size = height.size();
    vector<int> left_max(size), right_max(size);
    left_max[0] = height[0];
    for (int i = 1; i < size; i++) {
        left_max[i] = max(height[i], left_max[i - 1]);
    }
    right_max[size - 1] = height[size - 1];
    for (int i = size - 2; i >= 0; i--) {
        right_max[i] = max(height[i], right_max[i + 1]);
    }
    for (int i = 1; i < size - 1; i++) {
        ans += min(left_max[i], right_max[i]) - height[i];
    }
    return ans;
}

};

 

单调栈:

维护一个递减栈,栈中保存的是height数组下标,因为蓄水池宽度不一定为1,我们利用数组下标好计算宽度。

 

 

class Solution {
public:
    int trap(vector<int>& height) {
        int n=height.size();
        if(n<=2){
            return 0;
        }
        stack<int> sta;
        int res=0;
        int i=0;
        while(i<n){
            while(not sta.empty() and height[i]>=height[sta.top()]){
                int cur_top=sta.top();
                sta.pop();
                // cout<<"pop height["<<cur_top<<"]"<<height[cur_top]<<endl;
                if(sta.empty()){
                    break;
                }
                res+=(min(height[i],height[sta.top()])-height[cur_top])*(i-sta.top()-1);
                // cout<<"res="<<res<<endl;
            }
            sta.push(i++);
            // cout<<"push height["<<i-1<<"]"<<height[i-1]<<endl;
            
        }
        return res;
    }
};

 

posted @ 2020-04-04 14:10  NeoZy  阅读(126)  评论(0)    收藏  举报