public class TrappingRainWater {
public static int trw(int[] heights) {
if (heights == null || heights.length <= 1) {
return 0;
}
int maxHeight = 0;
for (int height : heights) {
if (height > maxHeight) {
maxHeight = height;
}
}
int [][] dp = new int[maxHeight+1][heights.length+1];
// i for height
for (int i = 1; i <= maxHeight; i++) {
// j for position
int start = 0;
int curLineLen = 0;
for (int j = 1; j <= heights.length; j++) {
if (heights[j-1] >= i) {
if (start != 0) {
curLineLen += (j - start - 1);
}
start = j;
}
dp[i][j] = curLineLen + dp[i-1][j];
}
}
return dp[maxHeight][heights.length];
}
public static void main(String[] args) {
System.out.println(trw(new int[]{0,1,0,2,1,0,1,3,2,1,2,1}));
System.out.println(trw(new int[]{4,2,0,3,2,5}));
}
}
解题思路:
构造dp数组, dp[i][j]代表i高度,j位置能收集到的雨水之和
i高度,j位置能收集到的雨水之和可拆分为2部分:
① 当前高度i,这一行能收集的雨水之和。
计算方式为从第1个位置记录高度大于i的位置, 每2个位置之间的空格数,即为这2个位置之间能容纳的雨水数。 从前向后遍历, 可容纳的雨水数累加即为此高度当前位置能容纳的最大雨水数。
② 比i高度低的j位置能容纳的雨水之和, 即 dp[i-1][j]
1.①与1.②之和, 即为i高度/j位置的最大雨水数量 dp[i][j]