42. 接雨水(困难)

给定 n 个非负整数表示每个宽度为 1 的柱子的高度图,计算按此排列的柱子,下雨之后能接多少雨水。

示例 1:

1
2
3
输入: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:

1
2
输入:height = [4,2,0,3,2,5]
输出:9

提示:

n == height.length
0 <= n <= 3 * 104
0 <= height[i] <= 105

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/trapping-rain-water

思路:

双指针

https://leetcode-cn.com/problems/trapping-rain-water/solution/42-jie-yu-shui-shuang-zhi-zhen-dong-tai-wguic/

代码1:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
class Solution {
public int trap(int[] height) {
if(height == null){
return 0;
}
int sum =0;
for(int i = 0;i<height.length;i++){
//第一步排除,第一个和最后一个
if(i==0 || i== height.length-1){
continue;
}
int lh = height[i];
int rh = height[i];
//找到i左右最高的
for(int j = i+1;j< height.length;j++){
if(height[j]>rh){
rh = height[j];
}
}
for(int j=i-1;j>=0;j--){
if(height[j]>lh){
lh = height[j];
}
}
//求
int h = Math.min(lh,rh)-height[i];
sum += h;
}
return sum;
}
}

代码2

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
class Solution {
public int trap(int[] height) {
int len = height.length;
if(len<=2){
return 0;
}
//使用两个数组来减少重复计算,其实也是记忆化
int[] rdp = new int[len];
int[] ldp = new int[len];
//初始化
ldp[0] = height[0];
for(int i=1;i<len;i++){
ldp[i] = Math.max(ldp[i-1],height[i]);
}
rdp[len-1] = height[len-1];
for (int i=len-2;i>0;i--){
rdp[i] = Math.max(rdp[i+1],height[i]);
}
//开始遍历
int sum = 0;
for(int i=0;i<len;i++){
int h = Math.min(ldp[i],rdp[i])-height[i];
if(h>0){
sum += h;
}
}
return sum;
}
}