leetcode刷题笔记【4】
分类:双指针|单调栈
42. 接雨水【困难】
给定 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
//竖着看
//数组存每一个位置的左边最高高度和右边最高高度
//时间复杂度o(n)
//空间复杂度o(n)
// class Solution {
// public int trap(int[] height) {
// int ans=0;
// int n = height.length;
// int[] lHeight = new int[n];
// lHeight[0]=height[0];
// for(int i=1;i<n;i++){
// lHeight[i]=Math.max(lHeight[i-1],height[i]);
// }
// int rHeight=height[n-1];
// for(int i=n-2;i>=0;i--){
// rHeight=Math.max(rHeight,height[i]);
// ans+=Math.min(lHeight[i],rHeight)-height[i];
// }
// return ans;
// }
// }
//空间优化
//双向双指针
//时间复杂度o(n)
//空间复杂度o(1)
// class Solution {
// public int trap(int[] height) {
// int ans=0;
// int n = height.length;
// int l=0,r=n-1;
// int l_max=0,r_max=0;
// while(l<r){
// l_max=Math.max(l_max,height[l]);
// r_max=Math.max(r_max,height[r]);
// if(l_max<r_max){
// ans+=l_max-height[l];
// l++;
// }else{
// ans+=r_max-height[r];
// r--;
// }
// }
// return ans;
// }
// }
//横着看
//单调栈
//单调递减
//时间复杂度o(n)
//空间复杂度o(n)
class Solution {
public int trap(int[] height) {
int ans=0;
int n = height.length;
List<Integer> st = new ArrayList<>();
for(int i=0;i<n;i++){
while(!st.isEmpty()&&height[i]>=height[st.getLast()]){
int bottom = height[st.removeLast()];
if(st.isEmpty()){
break;
}
int l=st.getLast();
ans+=(Math.min(height[l],height[i])-bottom)*(i-l-1);
}
st.add(i);
}
return ans;
}
}