LeetCode之接雨水

1.题目链接

https://leetcode.cn/problems/trapping-rain-water/

2.方法一:动态规划

动态规划思路:

如果我们暴力的来做这道题的话,我们就需要找到每一个坑洼处两边的最小值和最大值,但如果我们遍历每一个点来找其周围最大值和最小值的话就会很费时间,我们这时就可以正反两次遍历来记录每一个坑洼处两边的最大值,最后遍历计算面积即可。

奉上代码一:

class Solution {
public:
    int trap(vector<int>& height) {

        int n=height.size(),res=0;

        if(!height.size())
        return 0;

        vector<int> l(n),r(n);

        l[0]=height[0];
        for(int i=1;i<n;i++)
        l[i]=max(l[i-1],height[i]);

        r[n-1]=height[n-1];
        for(int i=n-2;i>=0;i--)
        r[i]=max(r[i+1],height[i]);
 
        for(int i=0;i<n;i++)
        res+=min(l[i],r[i])-height[i];

        return res;
    }
};

 

 2.方法一:双指针

双指针思路:

双指针的具体思路是使用两根指针分别指向序列头和序列尾,由于接到雨水的量是由一个坑洼处最低的边界决定的,所以我们要让两头指针中最低的那一端向内移动去寻找更高点(不然接雨水的量永远都被最低端限制,无法增加),倘若左指针小于右指针,我们首先要找到左边的最大值,否则不能接到雨水,然后我们往下面逐步遍历低洼处,逐步计算面积,右指针大于左指针时情况也是相同的。

奉上代码二:

class Solution {
public:
    int trap(vector<int>& height) {

        int l=0,r=height.size()-1;
        
        int l_max=0,r_max=0,res=0;

        while(l<r)
        {
            if(height[l]<=height[r])
            {
                if(height[l]>=l_max)
                l_max=height[l];

                else
                res+=l_max-height[l];
                l++;
            }

            else
            {
                if(height[r]>=r_max)
                r_max=height[r];

                else
                res+=r_max-height[r];
                r--;
            }
        }

        return res;
    }
};

 

4.方法三:单调栈

单调栈思路:

对于每一个坑洼处我们也可使用单调栈的思想来求解,由于栈中的元素是从栈底到栈顶是递减排列的,这时如果栈中元素数量大于两个,这时如果新元素大于栈顶元素,此时一定能形成一个坑洼来积水,最后逐步计算面积就可以了。

奉上代码三:

class Solution {
public:
    int trap(vector<int>& height) {

        int res=0;

        stack<int> s;

        for(int i=0;i<height.size();i++)
        {
            while(!s.empty()&&height[i] > height[s.top()])
            {
                int top=s.top();
                s.pop();

                if(s.empty())
                break;

                int l=s.top();
                res+=(i-l-1)*(min(height[l],height[i])-height[top]);
            }
            s.push(i);
        }

        return res;
    }
};

  • 11
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值