当前位置:网站首页>单调栈-42. 接雨水
单调栈-42. 接雨水
2022-07-03 08:24:00 【later_rql】
1.题目
给定 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
来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/trapping-rain-water
2.解题思路
共有是三种方法解决:
方法一:双指针法

然后,当前列的雨水高度等于,min(LH,RH)-当前列高度。
特殊情况:第一列和最后以列不操作。
方法二:动态规划
其实是对双指针法的一种优化,因为在使用双指针法的时候,发现,在求每列的左右最大值的时候,存在着重复的计算,如果利用动态规划的方法记录。
即从左向右遍历:maxLeft[i] = max(height[i], maxLeft[i - 1]);
从右向左遍历:maxRight[i] = max(height[i], maxRight[i + 1]);
方法三:单调栈

分为三种情况:
(1)如果当前遍历的元素(柱子)高度小于栈顶元素的高度,就把这个元素加入栈中,因为栈里本来就要保持从小到大的顺序(从栈头到栈底)。
(2)如果当前遍历的元素(柱子)高度等于栈顶元素的高度,要跟更新栈顶元素,因为遇到相相同高度的柱子,需要使用最右边的柱子来计算宽度。
(3)如果当前遍历的元素(柱子)高度大于栈顶元素的高度,此时就出现凹槽了(这种情况会出现雨水)
其实质就是:栈顶和栈顶的下一个元素以及要入栈的三个元素来接水!

凹槽的高度:int h = min(height[st.top()], height[i]) - height[mid];
凹槽的宽度:int w = i - st.top() - 1 ;
凹槽的体积:h*w
3.代码
方法一:双指针法(非最优)
public int trap(int[] height) {
int sum = 0;
for (int i = 0; i < height.length; i++) {
// 第一个柱子和最后一个柱子不接雨水
if (i==0 || i== height.length - 1) continue;
int rHeight = height[i]; // 记录右边柱子的最高高度
int lHeight = height[i]; // 记录左边柱子的最高高度
for (int r = i+1; r < height.length; r++) {
if (height[r] > rHeight) rHeight = height[r];
}
for (int l = i-1; l >= 0; l--) {
if(height[l] > lHeight) lHeight = height[l];
}
int h = Math.min(lHeight, rHeight) - height[i];
if (h > 0) sum += h;
}
return sum;
}
方法二:动态规划
public int trap(int[] height) {
int length = height.length;
if (length <= 2) return 0;
int[] maxLeft = new int[length];
int[] maxRight = new int[length];
// 记录每个柱子左边柱子最大高度
maxLeft[0] = height[0];
for (int i = 1; i< length; i++) maxLeft[i] = Math.max(height[i], maxLeft[i-1]);
// 记录每个柱子右边柱子最大高度
maxRight[length - 1] = height[length - 1];
for(int i = length - 2; i >= 0; i--) maxRight[i] = Math.max(height[i], maxRight[i+1]);
// 求和
int sum = 0;
for (int i = 0; i < length; i++) {
int count = Math.min(maxLeft[i], maxRight[i]) - height[i];
if (count > 0) sum += count;
}
return sum;
}
方法三:单调栈法
public int trap(int[] height){
int size = height.length;
if (size <= 2) return 0;
// in the stack, we push the index of array
// using height[] to access the real height
Stack<Integer> stack = new Stack<Integer>();
stack.push(0);
int sum = 0;
for (int index = 1; index < size; index++){
int stackTop = stack.peek();
if (height[index] < height[stackTop]){
stack.push(index);
}else if (height[index] == height[stackTop]){
// 因为相等的相邻墙,左边一个是不可能存放雨水的,所以pop左边的index, push当前的index
stack.pop();
stack.push(index);
}else{
//pop up all lower value
int heightAtIdx = height[index];
while (!stack.isEmpty() && (heightAtIdx > height[stackTop])){
int mid = stack.pop();
if (!stack.isEmpty()){
int left = stack.peek();
int h = Math.min(height[left], height[index]) - height[mid];
int w = index - left - 1;
int hold = h * w;
if (hold > 0) sum += hold;
stackTop = stack.peek();
}
}
stack.push(index);
}
}
return sum;
}
4.性能
方法一:双指针(非最优)
- 时间复杂度:O(n^2)
- 空间复杂度:O(l)
方法二:动态规划
- 时间复杂度:O(n)
- 空间复杂度:O(n)
方法三:单调栈
- 时间复杂度:O(n)
- 空间复杂度:O(n)
边栏推荐
- GIS实战应用案例100篇(七十八)-多规合一数据库设计及数据入库
- Unity editor expansion - the framework and context of unity imgui
- Jupyter remote server configuration and server startup
- Scite change background color
- Notes on understanding applets 2022/7/3
- 【云原生】微服务之Feign的介绍与使用
- Unity change default editor
- Unity Editor Extension - Outline
- Dotween plug-in
- UE4 plug in development
猜你喜欢

C#课程设计之员工信息管理系统

Un système de gestion de centre commercial pour la conception de cours de technologie d'application de base de données

Advanced OSG collision detection

【更新中】微信小程序学习笔记_3

Storage of data

Base64和Base64URL
![[set theory] order relation (the relation between elements of partial order set | comparable | strictly less than | covering | Haas diagram)](/img/df/a034032e203e7935dafaf8a71cb6c8.jpg)
[set theory] order relation (the relation between elements of partial order set | comparable | strictly less than | covering | Haas diagram)

梯度下降法求解BP神经网络的简单Demo

Puhua PLM empowers the whole scene product lifecycle management and helps the enterprise digital transformation of the main line of products

数据分析练习题
随机推荐
Osganimation library parsing
Unity editor expansion - the framework and context of unity imgui
UE4 plug in development
Transmit pictures with Base64 encoding
Golang's range
Base64和Base64URL
二进制转十进制,十进制转二进制
梯度下降法求解BP神经网络的简单Demo
【音视频】ijkplayer错误码
Intersectionpicker in osgearth
Mall management system of database application technology course design
String class
Flex flexible box layout
Introduction to Base64 coding
Clion toolchains are not configured configure disable profile problem solving
Redis的数据结构
Basic operation and process control
Unity Editor Extension - event handling
Osgearth starry background
Dotween plug-in