leetcode 42. 接雨水
题意:给定 n 个非负整数表示每个宽度为 1 的柱子的高度图,计算按此排列的柱子,下雨之后能接多少雨水。
思路:可以发现填满雨水后一定是一个先升序后降序的序列,也就是说对答案产生影响的只有从左边开始的升序序列和从右边开始的升序序列。考虑dp[i]表示从左边/右边开始的最大值,每次改变最大值的时候,根据左边/右边的上一个最大值计算出接满雨水后的面积加入到答案res中,并更新l/r指针,最后对整个序列求和,那么最终答案res = res - sum + (r - l)* height[l]
代码
import java.util.Arrays;
class Solution {
public int trap(int[] height) {
int dp[] = new int[height.length];
int l = 0;
int r = height.length - 1;
int res = 0;
Arrays.fill(dp, 0, height.length, 0);
dp[0] = height[0];
for(int i = 1;i < height.length; i++) {
if(height[i] > dp[i-1]) {
res += (i - l) * dp[i - 1];
dp[i] = height[i];
l = i;
} else dp[i] = dp[i - 1];
}
Arrays.fill(dp, 0, height.length, 0);
dp[height.length - 1] = height[height.length - 1];
for(int i = height.length - 2;i >= 0; i --) {
if(height[i] > dp[i + 1]) {
res += (r - i) * dp[i + 1];
dp[i] = height[i];
r = i;
} else dp[i] = dp[i + 1];
}
int sum = 0;
for(int i = 0;i < height.length;i ++) {
sum += height[i];
}
res += (r - l + 1) * height[l] - sum;
return res;
}
}