42. 接雨水

Posted fdwzy

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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)
{
    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;
    }
};

 

以上是关于42. 接雨水的主要内容,如果未能解决你的问题,请参考以下文章

leetcode 每日一题 42. 接雨水

每日一题:42. 接雨水

42. 接雨水

LeetCode42题动态规划 - 接雨水

11-1:(42)接雨水

LeetCode:接雨水42