41
41
42
42
<!-- 这里可写通用的实现逻辑 -->
43
43
44
- 动态规划法。
44
+ ** 方法一:动态规划 **
45
45
46
- 对于下标 i,水能达到的最大高度等于下标 i 左右两侧的最大高度的最小值,再减去 ` height[i] ` 就能得到当前柱子所能存的水量 。
46
+ 我们定义 $left [ i ] $ 表示下标 $i$ 位置及其左边的最高柱子的高度,定义 $right [ i ] $ 表示下标 $i$ 位置及其右边的最高柱子的高度。那么下标 $i$ 位置能接的雨水量为 $min(left [ i ] , right [ i ] ) - height[ i] $。我们遍历数组,计算出 $left [ i ] $ 和 $right [ i ] $,最后答案为 $\sum _ {i=0}^{n-1} min(left [ i ] , right [ i ] ) - height [ i ] $ 。
47
47
48
- 同 [ 面试题 17.21. 直方图的水量 ] ( /lcci/17.21.Volume%20of%20Histogram/README.md )
48
+ 时间复杂度 $O(n)$,空间复杂度 $O(n)$。其中 $n$ 为数组的长度。
49
49
50
50
<!-- tabs:start -->
51
51
57
57
class Solution :
58
58
def trap (self , height : List[int ]) -> int :
59
59
n = len (height)
60
- if n < 3 :
61
- return 0
62
-
63
- lmx, rmx = [height[0 ]] * n, [height[n - 1 ]] * n
60
+ left = [height[0 ]] * n
61
+ right = [height[- 1 ]] * n
64
62
for i in range (1 , n):
65
- lmx[i] = max (lmx[i - 1 ], height[i])
66
- rmx[n - 1 - i] = max (rmx[n - i], height[n - 1 - i])
67
-
68
- res = 0
69
- for i in range (n):
70
- res += min (lmx[i], rmx[i]) - height[i]
71
- return res
63
+ left[i] = max (left[i - 1 ], height[i])
64
+ right[n - i - 1 ] = max (right[n - i], height[n - i - 1 ])
65
+ return sum (min (l, r) - h for l, r, h in zip (left, right, height))
72
66
```
73
67
74
68
### ** Java**
@@ -79,108 +73,62 @@ class Solution:
79
73
class Solution {
80
74
public int trap (int [] height ) {
81
75
int n = height. length;
82
- if (n < 3 ) {
83
- return 0 ;
84
- }
85
-
86
- int [] lmx = new int [n];
87
- int [] rmx = new int [n];
88
- lmx[0 ] = height[0 ];
89
- rmx[n - 1 ] = height[n - 1 ];
76
+ int [] left = new int [n];
77
+ int [] right = new int [n];
78
+ left[0 ] = height[0 ];
79
+ right[n - 1 ] = height[n - 1 ];
90
80
for (int i = 1 ; i < n; ++ i) {
91
- lmx [i] = Math . max(lmx [i - 1 ], height[i]);
92
- rmx [n - 1 - i ] = Math . max(rmx [n - i], height[n - i - 1 ]);
81
+ left [i] = Math . max(left [i - 1 ], height[i]);
82
+ right [n - i - 1 ] = Math . max(right [n - i], height[n - i - 1 ]);
93
83
}
94
-
95
- int res = 0 ;
84
+ int ans = 0 ;
96
85
for (int i = 0 ; i < n; ++ i) {
97
- res += Math . min(lmx [i], rmx [i]) - height[i];
86
+ ans += Math . min(left [i], right [i]) - height[i];
98
87
}
99
- return res ;
88
+ return ans ;
100
89
}
101
90
}
102
91
```
103
92
104
- ### ** TypeScript**
105
-
106
- ``` ts
107
- function trap(height : number []): number {
108
- let ans = 0 ;
109
- let left = 0 ,
110
- right = height .length - 1 ;
111
- let maxLeft = 0 ,
112
- maxRight = 0 ;
113
- while (left < right ) {
114
- if (height [left ] < height [right ]) {
115
- // move left
116
- if (height [left ] >= maxLeft ) {
117
- maxLeft = height [left ];
118
- } else {
119
- ans += maxLeft - height [left ];
120
- }
121
- ++ left ;
122
- } else {
123
- // move right
124
- if (height [right ] >= maxRight ) {
125
- maxRight = height [right ];
126
- } else {
127
- ans += maxRight - height [right ];
128
- }
129
- -- right ;
130
- }
131
- }
132
- return ans ;
133
- }
134
- ```
135
-
136
93
### ** C++**
137
94
138
95
``` cpp
139
96
class Solution {
140
97
public:
141
98
int trap(vector<int >& height) {
142
99
int n = height.size();
143
- if (n < 3) {
144
- return 0;
145
- }
146
-
147
- vector<int> lmx(n, height[0]);
148
- vector<int> rmx(n, height[n - 1]);
100
+ int left[ n] , right[ n] ;
101
+ left[ 0] = height[ 0] ;
102
+ right[ n - 1] = height[ n - 1] ;
149
103
for (int i = 1; i < n; ++i) {
150
- lmx [i] = max(lmx [i - 1], height[i]);
151
- rmx [n - 1 - i ] = max(rmx [n - i], height[n - 1 - i ]);
104
+ left [ i] = max(left [ i - 1] , height[ i] );
105
+ right [ n - i - 1 ] = max(right [ n - i] , height[ n - i - 1 ] );
152
106
}
153
-
154
- int res = 0 ;
107
+ int ans = 0;
155
108
for (int i = 0; i < n; ++i) {
156
- res += min(lmx [i], rmx [i]) - height[i];
109
+ ans += min(left [ i] , right [ i] ) - height[ i] ;
157
110
}
158
- return res ;
111
+ return ans ;
159
112
}
160
113
};
161
114
```
162
115
163
116
### **Go**
164
117
165
118
```go
166
- func trap (height []int ) int {
119
+ func trap(height []int) (ans int) {
167
120
n := len(height)
168
- if n < 3 {
169
- return 0
170
- }
171
-
172
- lmx , rmx := make ([]int , n), make ([]int , n)
173
- lmx[0 ], rmx[n-1 ] = height[0 ], height[n-1 ]
121
+ left := make([]int, n)
122
+ right := make([]int, n)
123
+ left[0], right[n-1] = height[0], height[n-1]
174
124
for i := 1; i < n; i++ {
175
- lmx [i] = max (lmx [i-1 ], height[i])
176
- rmx [n-1 -i ] = max (rmx [n-i], height[n-1 -i ])
125
+ left [i] = max(left [i-1], height[i])
126
+ right [n-i-1 ] = max(right [n-i], height[n-i-1 ])
177
127
}
178
-
179
- res := 0
180
- for i := 0 ; i < n; i++ {
181
- res += min (lmx[i], rmx[i]) - height[i]
128
+ for i, h := range height {
129
+ ans += min(left[i], right[i]) - h
182
130
}
183
- return res
131
+ return
184
132
}
185
133
186
134
func max(a, b int) int {
@@ -198,6 +146,25 @@ func min(a, b int) int {
198
146
}
199
147
```
200
148
149
+ ### ** TypeScript**
150
+
151
+ ``` ts
152
+ function trap(height : number []): number {
153
+ const n = height .length ;
154
+ const left: number [] = new Array (n ).fill (height [0 ]);
155
+ const right: number [] = new Array (n ).fill (height [n - 1 ]);
156
+ for (let i = 1 ; i < n ; ++ i ) {
157
+ left [i ] = Math .max (left [i - 1 ], height [i ]);
158
+ right [n - i - 1 ] = Math .max (right [n - i ], height [n - i - 1 ]);
159
+ }
160
+ let ans = 0 ;
161
+ for (let i = 0 ; i < n ; ++ i ) {
162
+ ans += Math .min (left [i ], right [i ]) - height [i ];
163
+ }
164
+ return ans ;
165
+ }
166
+ ```
167
+
201
168
### ** ...**
202
169
203
170
```
0 commit comments