题目内容

给定 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 * 104
0 <= height[i] <= 105

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

解题思路

这道题我一开始也是没有什么头绪,正准备看题解,结果看到单调栈标题,瞬间就懂了(有时候还真的是要多练习才能有一些敏锐度,我都没想到这个)。于是回过头来准备自己写这个。恬不知耻一些,这个也算大半个自己写的吧(doge)。

其实单调栈对于这类问题来说几乎就是天作之合了,单调栈最好的用处就是寻找数组中离自己最近的,比自己大或者小的元素的位置,在这道题这里正好可以看一下积攒雨水的柱子的位置。

我们先来看一下单调栈结构解决找元素位置问题,这个其实我们可以用O(n^2)来解决,但是单调栈的存在可以把这个问题优化到O(N)

我们先说数组中没有重复值的情况,这样好理解一些。如果我们要找的是最近的比自己大的数,那么我们就需要确定一点,那就是单调栈是从大到小排列的(栈底到栈顶)。满足条件的时候,我们直接压栈,但是如果发现有不满足的了,就需要出栈了,然后弹出栈顶之后,他左边的比他大的就是栈里他下面那个,右边那个就是进栈未遂的数据。如果没有就是无,这里会一直出栈知道能够进栈为止。这里一个数据进出栈都只有一次,所以时间复杂度是O(N)

回到题目,首先就是用单调栈实现对于每一个位置找左右比自己高的位置的脚标,这里需要注意的是,最好用脚标才入栈,因为脚标的信息和高度是包含关系,脚标信息更多一些。

然后把所有能找到左右比自己高的位置存在map里,这里其实如果留心一些会发现我们的栈中还是有元素没有出来的,这个就不用管了,这个说明我们最右边有一个下坡的形态,是根本存不下水的。

有了这个数据之后就好处理多了,直接遍历,计算两边柱子能提供的高度-本身的高度。不过在计算好了之后,记得要更新height的数据,不然的话因为存在嵌套关系,会导致结果出现问题。

代码

class Solution {public:int trap(vector<int>& height) {stack<int> dandiao;map<int,pair<int,int>> mp;for(int i=0;i<height.size();i++){if(dandiao.size()==0){dandiao.push(i);}else{if(height[dandiao.top()]>height[i]){dandiao.push(i);}else{while(height[dandiao.top()]<=height[i]){int weizhi=dandiao.top();dandiao.pop();int ding=dandiao.size()==0?-1:dandiao.top();if(mp.find(i)==mp.end()){mp[weizhi]=pair<int,int>(ding,i);}else{mp[weizhi]=pair<int,int>(ding,i);}if(dandiao.size()==0){break;}}dandiao.push(i);}}}cout<<mp.size()<<endl;int ans=0;for(int i=0;i<height.size();i++){cout<<i<<":"<<mp[i].first<<"  "<<mp[i].second<<endl;if(mp[i].first==-1){continue;}int low=min(height[mp[i].first],height[mp[i].second]);cout<<low<<endl;for(int j=mp[i].first+1;j<mp[i].second;j++){ans+=((low-height[j]>0)?low-height[j]:0);height[j]=low;cout<<ans<<endl;}}return ans;}
};

使用单调栈解决接雨水问题——LeetCode 42 接雨水+单调栈说明相关推荐

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

    文章目录 1. 题目 2. 解题 2.1 正反扫描法 2.2 双指针 2.3 单调栈 1. 题目 给定 n 个非负整数表示每个宽度为 1 的柱子的高度图,计算按此排列的柱子,下雨之后能接多少雨水. 上 ...

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

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

  3. leetcode 42 接雨水 单调栈

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

  4. Leetcode 42.接雨水 (每日一题 20210629)

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

  5. 【LeetCode - 42. 接雨水】

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

  6. leetcode 42. 接雨水

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

  7. 【LeetCode刷题日记】栈类题目常见题型

    文章目录 [20. 有效的括号](https://leetcode-cn.com/problems/valid-parentheses/) [225. 用队列实现栈](https://leetcode ...

  8. 【栈】python、单调栈解决收集雨水问题、力扣42题

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

  9. 将一个数组中的值按逆序重新排放。_六十五、下一个更大的数系列,单调栈解决方法...

    「@Author:Runsen」 ❝ 编程的本质来源于算法,而算法的本质来源于数学,编程只不过将数学题进行代码化. 「---- Runsen」 ❞ 据说,放张小姐姐觉得照片可以提高阅读量,图是来源学校 ...

最新文章

  1. Ubuntu 安装 搜狗输入法
  2. java doc 编写
  3. pythonis啥意思-isinstance在python中的意思是什么?
  4. 微云存照片会变模糊吗_保存照片的最佳方式是网盘、硬盘、SSD还是光盘?
  5. Java中如何引用另一个类里的集合_【18期】Java序列化与反序列化三连问:是什么?为什么要?如何做?...
  6. 符号未定义Java_Java ODBC数据源(未定义符号:SQLAllocEnv)
  7. websocket实现单聊
  8. 一台路由器实现电信ITV与宽带共享上网
  9. for循环执行 mybatis_mybatis sql循环的使用
  10. 网络知识:整理各种路由器组网方法!网跨段也能访问!
  11. 世界是沙粒还是宇宙_看到一个沙粒世界:再一次你好世界
  12. [2013-08-19] nohup的使用
  13. python json模块详解_深入解析Python编程中JSON模块的使用
  14. 微机原理及应用实验——汇编环境MASM的使用
  15. 诺基亚3090微信java,适合Asha系列,微信登陆诺基亚S40平台
  16. QT 代码添加QScrollArea
  17. PHP读取HTML生成doc
  18. 采用numpy快速将两个矩阵或数组合并成一个数组和行列转置
  19. Ubuntu软件包升级失败的终极修复方法
  20. 基于JAVA框架的电脑测评系统计算机毕业设计源码+系统+mysql数据库+lw文档+部署

热门文章

  1. Linux安装perl
  2. 华为手机可以分屏吗_你知道华为手机怎么投屏到电视上去吗?原来华为手机这么厉害...
  3. 可以去视频的水印的软件 视频伪原创
  4. python怎么训练分类器_[ Pytorch教程 ] 训练分类器 - pytorch中文网
  5. 目前最全的Python的就业方向
  6. python树莓派编程书籍_有哪些优秀的讲解 树莓派开发 的书籍?
  7. Android Studio下载SDK资源慢怎么办
  8. 《庆余年》全集盗版泄露,女主角很生气,网友评论也是亮了
  9. 如何使用onyx for mac显示更多系统硬件信息
  10. 英语口语144之每日十句口语