LeetCode42-接雨水

LeetCode42-接雨水

Leetcode / 力扣

42. 接雨水:

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

在这里插入图片描述

示例 1:

输入:height = [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 个单位的雨水(蓝色部分表示雨水)。 

示例 2:

输入:height = [4,2,0,3,2,5]
输出:9

提示:

  • n == height.length
  • 1 <= n <= 2 * 10^4
  • 0 <= height[i] <= 10^5

可以参考官方题解,写得挺详细的
官方题解传送门

解题思路1:

预处理左右最值,第i出的最大存水量就是和左右最值的最小值有关

class Solution {
public:
    int trap(vector<int>& height) {
        int len=height.size();
        vector<int>maxleft(len);
        vector<int>maxright(len);

        maxleft[0]=height[0];
        for(int i=1;i<len;++i)
            maxleft[i]=max(maxleft[i-1],height[i]);
        maxright[len-1]=height[len-1];
        for(int i=len-2;i>=0;--i)
            maxright[i]=max(maxright[i+1],height[i]);

        int ans=0;
        for(int i=0;i<len;++i)
            ans+=min(maxleft[i],maxright[i])-height[i];

        return ans;
    }
};

解题思路2:

双指针,考虑一直移动小的一边,计算当前这个格子可以存水量即可

class Solution {
public:
    int trap(vector<int>& height) {
        int ans=0;
        int len=height.size();
        int l=0,r=len-1;
        int leftmax=0,rightmax=0;
        while(l<=r) {
            leftmax=max(height[l],leftmax);
            rightmax=max(height[r],rightmax);
            if(height[l]>=height[r]) {
                ans+=rightmax-height[r];
                --r;
            }
            else {
                ans+=leftmax-height[l];
                ++l;
            }
            //cout<<"ans="<<ans<<endl;
        }
        return ans;
    }
};

解题思路3:

维护一个下标单调不增栈,当遇到比栈顶元素大的数值时候,我们就可以计算这个点的积水量,因为左右两边都比栈顶元素大,可以形成挡板,形成积水

class Solution {
public:
    int trap(vector<int>& height) {
        int len=height.size();
        int ans=0;
        stack<int>s;
        for(int i=0;i<len;++i) {
            while(!s.empty() && height[i]>height[s.top()]) {
                int now=s.top();
                s.pop();
                if(s.empty())
                    break;
                int curLength=i-s.top()-1;
                int curHeight=min(height[i],height[s.top()])-height[now];
                ans+=curLength*curHeight;
            }
            s.push(i);
        }
        return ans;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值