Skip to content

Commit a1f5f49

Browse files
FanFan0919labuladong
authored andcommitted
【42. 接雨水】【Java】
1 parent 0ad9a50 commit a1f5f49

File tree

1 file changed

+96
-1
lines changed

1 file changed

+96
-1
lines changed

高频面试系列/接雨水.md

Lines changed: 96 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -211,4 +211,99 @@ if (l_max < r_max) {
211211
<img src="../pictures/qrcode.jpg" width=200 >
212212
</p>
213213

214-
======其他语言代码======
214+
======其他语言代码======
215+
216+
[Yifan Zhang](https://github.com/FanFan0919) 提供 java 代码
217+
218+
**双指针解法**:时间复杂度 O(N),空间复杂度 O(1)
219+
220+
对cpp版本的解法有非常微小的优化。
221+
因为我们每次循环只会选 left 或者 right 处的柱子来计算,因此我们并不需要在每次循环中同时更新`maxLeft``maxRight`
222+
我们可以先比较 `maxLeft``maxRight`,决定这次选择计算的柱子是 `height[left]` 或者 `height[right]` 后再更新对应的 `maxLeft``maxRight`
223+
当然这并不会在时间上带来什么优化,只是提供一种思路。
224+
225+
```java
226+
class Solution {
227+
public int trap(int[] height) {
228+
if (height == null || height.length == 0) return 0;
229+
int left = 0, right = height.length - 1;
230+
int maxLeft = height[left], maxRight = height[right];
231+
int res = 0;
232+
233+
while (left < right) {
234+
// 比较 maxLeft 和 maxRight,决定这次计算 left 还是 right 处的柱子
235+
if (maxLeft < maxRight) {
236+
left++;
237+
maxLeft = Math.max(maxLeft, height[left]); // update maxLeft
238+
res += maxLeft - height[left];
239+
} else {
240+
right--;
241+
maxRight = Math.max(maxRight, height[right]); // update maxRight
242+
res += maxRight - height[right];
243+
}
244+
}
245+
246+
return res;
247+
}
248+
}
249+
```
250+
251+
附上暴力解法以及备忘录解法的 java 代码
252+
253+
**暴力解法**:时间复杂度 O(N^2),空间复杂度 O(1)
254+
```java
255+
class Solution {
256+
public int trap(int[] height) {
257+
if (height == null || height.length == 0) return 0;
258+
int n = height.length;
259+
int res = 0;
260+
// 跳过最左边和最右边的柱子,从第二个柱子开始
261+
for (int i = 1; i < n - 1; i++) {
262+
int maxLeft = 0, maxRight = 0;
263+
// 找右边最高的柱子
264+
for (int j = i; j < n; j++) {
265+
maxRight = Math.max(maxRight, height[j]);
266+
}
267+
// 找左边最高的柱子
268+
for (int j = i; j >= 0; j--) {
269+
maxLeft = Math.max(maxLeft, height[j]);
270+
}
271+
// 如果自己就是最高的话,
272+
// maxLeft == maxRight == height[i]
273+
res += Math.min(maxLeft, maxRight) - height[i];
274+
}
275+
return res;
276+
}
277+
}
278+
```
279+
280+
**备忘录解法**:时间复杂度 O(N),空间复杂度 O(N)
281+
```java
282+
class Solution {
283+
public int trap(int[] height) {
284+
if (height == null || height.length == 0) return 0;
285+
int n = height.length;
286+
int res = 0;
287+
// 数组充当备忘录
288+
int[] maxLeft = new int[n];
289+
int[] maxRight = new int[n];
290+
// 初始化 base case
291+
maxLeft[0] = height[0];
292+
maxRight[n - 1] = height[n - 1];
293+
294+
// 从左向右计算 maxLeft
295+
for (int i = 1; i < n; i++) {
296+
maxLeft[i] = Math.max(maxLeft[i - 1], height[i]);
297+
}
298+
// 从右向左计算 maxRight
299+
for (int i = n - 2; i >= 0; i--) {
300+
maxRight[i] = Math.max(maxRight[i + 1], height[i]);
301+
}
302+
// 计算答案
303+
for (int i = 1; i < n; i++) {
304+
res += Math.min(maxLeft[i], maxRight[i]) - height[i];
305+
}
306+
return res;
307+
}
308+
}
309+
```

0 commit comments

Comments
 (0)