前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >LeetCode 42. 接雨水(双指针、单调栈)

LeetCode 42. 接雨水(双指针、单调栈)

作者头像
Michael阿明
发布2020-07-13 15:40:38
1.1K0
发布2020-07-13 15:40:38
举报

1. 题目

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

上面是由数组 0,1,0,2,1,0,1,3,2,1,2,1 表示的高度图,在这种情况下,可以接 6 个单位的雨水(蓝色部分表示雨水)。 感谢 Marcos 贡献此图。

代码语言:javascript
复制
示例:
输入: [0,1,0,2,1,0,1,3,2,1,2,1]
输出: 6

来源:力扣(LeetCode)

链接:https://leetcode-cn.com/problems/trapping-rain-water

著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

2. 解题

类似题目:

LeetCode 11. 盛最多水的容器(双指针)

LeetCode 84. 柱状图中最大的矩形(单调递增栈)

2.1 正反扫描法

  • 正向扫描记录每个位置的历史最大值存入,反向亦然
  • 每个位置取上面得到的较小的值减去自身高度
代码语言:javascript
复制
class Solution {
public:
    int trap(vector<int>& h) {
    	if(h.empty())
    		return 0;
        int i = 0, s = 0, n = h.size();
        int Lmax[n], Rmax[n];
        Lmax[0] = h[0];
        for(i = 1; i < n; ++i)
        	Lmax[i] = max(h[i],Lmax[i-1]);
        Rmax[n-1] = h[n-1];
        for(i = n-2; i >= 0; --i)
        	Rmax[i] = max(h[i],Rmax[i+1]);
        for(i = 1; i < n-1; ++i)//两边永远装不了水
        	s += min(Lmax[i],Rmax[i])-h[i];
        return s;
    }
};

2.2 双指针

代码语言:javascript
复制
class Solution {
public:
    int trap(vector<int>& h) {
    	if(h.empty())
    		return 0;
        int l = 0, r = h.size()-1, s = 0;
        int Lmax = 0, Rmax = 0;
        while(l < r)
        {
        	if(h[l] < h[r])//右边肯定有堵高墙
        	{
        		h[l] >= Lmax ? (Lmax = h[l]) : s += Lmax-h[l];
        		//我不是左边最高的,就能盛水
        		++l;
        	}
        	else//h[l] >= h[r], 左边肯定有堵高墙
        	{
        		h[r] >= Rmax ? (Rmax = h[r]) : s += Rmax-h[r];
        		//我不是右边最高的,就能盛水
        		--r;
        	}
        }
        return s;
    }
};

2.3 单调栈

  • 单调递减栈相当于维护了左边的高墙
  • 遇到当前位置大于栈顶元素,就找到右边高墙
  • 计算栈顶元素可以接水量,删除栈顶
  • 循环判断直到当前位置 <= 栈顶(不能储水)
代码语言:javascript
复制
class Solution {
public:
    int trap(vector<int>& h) {
        if(h.empty())
            return 0;
        int s = 0, top, distance, height;
        stack<int> stk;
        for(int i = 0; i < h.size(); ++i)
        {
            while(!stk.empty() && h[i] > h[stk.top()])//当前墙高于左边的,违反递减
            {	//需要把中间高度比我小的处理掉,保持栈内单调递减
                top = stk.top();//左边的墙 位置记为top(待处理的)
                stk.pop();//删除之(处理掉)
                if(stk.empty())//top它没有左边围墙了
                    break;
                distance = i-stk.top()-1;//top左边还有墙
                height = min(h[i],h[stk.top()]) - h[top];
                //两边的最低高度(水高) - 自身高度(容器厚度)
                s += distance*height;
            }//处理完了,现在栈内是递减的了 或者 空
            stk.push(i);//递减的话会一直push进来(一个\斜坡,存不住水)
            //一旦不是斜坡了,进入上面的循环
        }
        return s;
    }
};
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2019/10/31 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1. 题目
  • 2. 解题
    • 2.1 正反扫描法
      • 2.2 双指针
        • 2.3 单调栈
        相关产品与服务
        容器服务
        腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档