当前位置:网站首页>单调栈-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)
边栏推荐
- Puhua PLM empowers the whole scene product lifecycle management and helps the enterprise digital transformation of the main line of products
- Un système de gestion de centre commercial pour la conception de cours de technologie d'application de base de données
- MySQL 8
- Golang的range
- C语言-入门-精华版-带你走进编程(一)
- Redis data structure
- Unity editor expansion - draw lines
- Development material set
- 【K&R】中文第二版 个人题解 Chapter1
- How does unity fixedupdate call at a fixed frame rate
猜你喜欢
Base64 and base64url
Kwai 20200412 recruitment
Shader foundation 01
Detailed explanation of all transfer function (activation function) formulas of MATLAB neural network
Storage of data
animation
Flex flexible box layout
[cloud native] introduction and use of feign of microservices
【更新中】微信小程序学习笔记_3
Kunlunbase meetup is waiting for you!
随机推荐
Xlua task list youyou
Golang json格式和结构体相互转换
【更新中】微信小程序学习笔记_3
Why can void * be a general pointer
[set theory] order relation (hastu example | divisive relation hastu | inclusive relation hastu | refinement relation hastu)
使用base64编码传图片
Huawei interview summary during the epidemic
Installation of PHP FPM software +openresty cache construction
简易入手《SOM神经网络》的本质与原理
Unity editor expansion - controls, layouts
Golang中删除字符串的最后一个字符
php-fpm软件的安装+openresty高速缓存搭建
Display terrain database on osgearth ball
Three characteristics
Unity editor expansion - the design idea of imgui
Simple demo of solving BP neural network by gradient descent method
UE4 call DLL
Basic operation and process control
Visual Studio (VS) shortcut keys
梯度下降法求解BP神经网络的简单Demo