102 lines
3.3 KiB
Java
Raw Normal View History

2025-04-02 18:28:11 +08:00
package stack;
import java.util.Deque;
import java.util.LinkedList;
/**
* 题目 42. 接雨水 (trap)
* 描述给定 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 个单位的雨水蓝色部分表示雨水
*
* 链接https://leetcode.cn/problems/trapping-rain-water/
*/
//困难题 不会
public class Trap {
//暴力解法
public int trap1(int[] height) {
int sum = 0;
for (int i = 0; i < height.length; i++) {
// 第一个柱子和最后一个柱子不接雨水
if (i == 0 || i == height.length - 1) {
continue;
}
int rHeight = height[i]; // 记录右边柱子的最高高度
int lHeight = height[i]; // 记录左边柱子的最高高度
for (int r = i + 1; r < height.length; r++) {
if (height[r] > rHeight) {
rHeight = height[r];
}
}
for (int l = i - 1; l >= 0; l--) {
if (height[l] > lHeight) {
lHeight = height[l];
}
}
int h = Math.min(lHeight, rHeight) - height[i];
if (h > 0) {
sum += h;
}
}
return sum;
}
//动态规划
public int trap2(int[] height) {
if (height.length <= 2) return 0;
int n = height.length;
int[] maxLeft = new int[n];
int[] maxRight = new int[n];
// 记录每个柱子左边柱子最大高度
maxLeft[0] = height[0];
for (int i = 1; i < n; i++) {
maxLeft[i] = Math.max(height[i], maxLeft[i - 1]);
}
// 记录每个柱子右边柱子最大高度
maxRight[n - 1] = height[n - 1];
for (int i = n - 2; i >= 0; i--) {
maxRight[i] = Math.max(height[i], maxRight[i + 1]);
}
// 求和
int sum = 0;
for (int i = 1; i < n-1; i++) {
int count = Math.min(maxLeft[i-1], maxRight[i+1]) - height[i];
if (count > 0) {
sum += count;
}
}
return sum;
}
//单调栈
public int trap(int[] height) {
int sum = 0;
Deque<Integer> stack = new LinkedList<>();
for (int i = 0; i < height.length; i++) {
// 当栈不为空且当前柱子的高度大于栈顶柱子的高度时
while (!stack.isEmpty() && height[i] > height[stack.peek()]) {
int top = stack.pop();
// 如果栈为空,则没有左边的柱子来接雨水
if (stack.isEmpty()) break;
// 计算当前柱子与栈顶柱子之间的距离
int distance = i - stack.peek() - 1;
// 计算可以接的雨水高度:两边较低的高度减去中间柱子的高度
int boundedHeight = Math.min(height[i], height[stack.peek()]) - height[top];
sum += distance * boundedHeight;
}
// 将当前索引入栈
stack.push(i);
}
return sum;
}
}