LC.P42[接雨水]

方法一:单调栈

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class Solution {
public int trap(int[] height) {
Deque<Integer> stack = new ArrayDeque<>();
int ans = 0, n = height.length;
for (int i = 0; i < n; ++i) {
while (!stack.isEmpty() && height[i] > height[stack.peek()]) {
int h = height[stack.pop()];
if (stack.isEmpty()) break;
int length = i - stack.peek() - 1;
int min = Math.min(height[stack.peek()], height[i]);
ans += length * (min - h);
}
stack.push(i);
}
return ans;
}
}
  • 时间复杂度:$O(n)$
  • 空间复杂度:$O(n)$

方法二:动态规划

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class Solution {
public int trap(int[] height) {
int n = height.length;
int[] leftMax = new int[n], rightMax = new int[n];
leftMax[0] = height[0];
rightMax[n - 1] = height[n - 1];
for (int i = 1; i < n; ++i) {
leftMax[i] = Math.max(leftMax[i - 1], height[i]);
rightMax[n - i - 1] = Math.max(rightMax[n - i], height[n - i - 1]);
}
int ans = 0;
for (int i = 0; i < n; ++i) {
ans += Math.min(leftMax[i], rightMax[i]) - height[i];
}
return ans;
}
}
  • 时间复杂度:$O(n)$
  • 空间复杂度:$O(n)$

方法三:双指针

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class Solution {
public int trap(int[] height) {
int ans = 0, n = height.length;
int left = 0, right = n - 1, leftMax = 0, rightMax = 0;
while (left < right) {
leftMax = Math.max(leftMax, height[left]);
rightMax = Math.max(rightMax, height[right]);
if (height[left] < height[right]) {
ans += leftMax - height[left];
++left;
} else {
ans += rightMax - height[right];
--right;
}
}
return ans;
}
}
  • 时间复杂度:$O(n)$
  • 空间复杂度:$O(1)$