文章目录

  • 1. 题目
  • 2. 解题
    • 2.1 正反扫描法
    • 2.2 双指针
    • 2.3 单调栈

1. 题目

给定 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

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/trapping-rain-water
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

2. 解题

类似题目:
LeetCode 11. 盛最多水的容器(双指针)
LeetCode 84. 柱状图中最大的矩形(单调递增栈)

2.1 正反扫描法

  • 正向扫描记录每个位置的历史最大值存入,反向亦然
  • 每个位置取上面得到的较小的值减去自身高度
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 双指针

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 单调栈

  • 单调递减栈相当于维护了左边的高墙
  • 遇到当前位置大于栈顶元素,就找到右边高墙
  • 计算栈顶元素可以接水量,删除栈顶
  • 循环判断直到当前位置 <= 栈顶(不能储水)
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;}
};

LeetCode 42. 接雨水(双指针、单调栈)相关推荐

  1. leetcode 42. 接雨水 思考分析(暴力、动态规划、双指针、单调栈)

    目录 题目 思路 暴力法 动态规划 双指针法 单调栈 题目 给定 n 个非负整数表示每个宽度为 1 的柱子的高度图,计算按此排列的柱子,下雨之后能接多少雨水. 输入:height = [0,1,0,2 ...

  2. 使用单调栈解决接雨水问题——LeetCode 42 接雨水+单调栈说明

    题目内容 给定 n 个非负整数表示每个宽度为 1 的柱子的高度图,计算按此排列的柱子,下雨之后能接多少雨水. 示例 1: 输入:height = [0,1,0,2,1,0,1,3,2,1,2,1] 输 ...

  3. leetcode 42 接雨水 单调栈

    接雨水 给定 n 个非负整数表示每个宽度为 1 的柱子的高度图,计算按此排列的柱子,下雨之后能接多少雨水. 上面是由数组 [0,1,0,2,1,0,1,3,2,1,2,1] 表示的高度图,在这种情况下 ...

  4. 【LeetCode - 42. 接雨水】

    42. 接雨水 难度困难3164 给定 n 个非负整数表示每个宽度为 1 的柱子的高度图,计算按此排列的柱子,下雨之后能接多少雨水. 示例 1: 输入:height = [0,1,0,2,1,0,1, ...

  5. LeetCode 321. 拼接最大数(单调栈)*

    文章目录 1. 题目 2. 解题 1. 题目 给定长度分别为 m 和 n 的两个数组,其元素由 0-9 构成,表示两个自然数各位上的数字. 现在从这两个数组中选出 k (k <= m + n) ...

  6. LeetCode 901. 股票价格跨度(单调栈)

    1. 题目 编写一个 StockSpanner 类,它收集某些股票的每日报价,并返回该股票当日价格的跨度. 今天股票价格的跨度被定义为股票价格小于或等于今天价格的最大连续日数(从今天开始往回数,包括今 ...

  7. LeetCode 739. 每日温度(单调栈)

    1. 题目 根据每日 气温 列表,请重新生成一个列表,对应位置的输入是你需要再等待多久温度才会升高超过该日的天数.如果之后都不会升高,请在该位置用 0 来代替. 例如,给定一个列表 temperatu ...

  8. leetcode 321. 拼接最大数(单调栈)

    给定长度分别为 m 和 n 的两个数组,其元素由 0-9 构成,表示两个自然数各位上的数字.现在从这两个数组中选出 k (k <= m + n) 个数字拼接成一个新的数,要求从同一个数组中取出的 ...

  9. 【leetcode刷题笔记】单调栈

    典型例题:求左边第一个比当前元素小的数 (模板,弄懂) 代码: #include<iostream> using namespace std; #include<stack> ...

最新文章

  1. dropout理解(一)
  2. Asp.Net 数据分页
  3. REVERSE-PRACTICE-BUUCTF-2
  4. Centos7上卸载openJdk安装,安装自己的JDK1.8
  5. Intel Sandy Bridge/Ivy Bridge架构/微架构/流水线 (3) - 流水线概述
  6. JavaScript命名冲突不可避免?
  7. jquery层级原则器(匹配前一个元素后的下一个元素,必须是挨着的)
  8. matlab按图像边缘抠图_Ps最全十大抠图方法都在这,最后一种万能「值得收藏」...
  9. 关于sentaurus使用感
  10. BZOJ1299 巧克力棒
  11. 单车架的ANSYS有限元分析
  12. Chloe.ORM框架使用之查询(一)
  13. shields 徽标_纽约公共图书馆的新徽标
  14. 北京最牛的医院 最牛的科室排名出炉
  15. Kaggle数据集之电信客户流失数据分析
  16. spirng中bean对象的作用范围
  17. 《科研诚信与学术规范》
  18. 第10节_我的日记本开发手记(10)——使用自定义图标字体
  19. 零基础入门推荐系统 - 新闻推荐(一)
  20. CH340进行STM32单片机程序烧录

热门文章

  1. smart gesture安装失败_WinCC flexible SMART V3 SP2安装步骤以及常见错误解决方法
  2. 常用的几种卷积神经网络介绍
  3. ReactiveCocoa简单介绍
  4. 如何解决类模板的分离编译问题?
  5. 生成 excel 直接用 httpServletResponse 输出
  6. 【原】jQuery编写插件
  7. DIV Scroll属性
  8. IBM软件服务创新运用 提升市民生活质量
  9. Blend设计VSM
  10. Server操作Mxd文件详细讲解