解题思路
平凡解法:感觉这个题的难点在于理解题意,找出具体位置上的雨水是如何计算得出的就好办了,显然一个位置所能存放雨水的值为其两边的最大的值的较小值减去在该位置的柱子长度既可以求得。
那么遍历所有的位置,并在遍历的同时求某个位置上的左边最大值和其右边最大值既可以求得该位置的储水量。
求和即可得到答案。整体时间复杂度为O(n2)。
动态规划:
既然要求所有位置的左边最大值,那么我们可以采用一个dp数组来记录每个位置上的左边最大值,遍历求这个leftMax[]的值即可,每个位置只需要对比当前位置的高度和前一个位置的leftMax值即可求得该位置的左边最大值。同理从右向左遍历可以求得所有元素的右边最大值。
有了这两个数组的值,我们在采用一次遍历即可求得所有的存水量。整体复杂度为O(n).
代码
平凡解法:
class Solution {
public int trap(int[] height) {
int len = height.length;
int sum = 0;
for(int i = 0;i<len ;i++){
int leftMax =0,rightMax = 0;
for(int j = 0;j<=i;j++){
leftMax = Math.max(leftMax, height[j]);
}
for(int k = i;k<len;k++){
rightMax = Math.max(rightMax, height[k]);
}
sum += Math.min(leftMax, rightMax) - height[i];
}
return sum;
}
}
动态规划:
public int trap(int[] height) {
int len = height.length;
int leftMax [] = new int[len];
int rightMax [] = new int [len];
leftMax[0] =height[0];
rightMax[len-1] = height[len-1];
for(int i =1;i<len;i++){
leftMax[i] = Math.max(leftMax[i-1], height[i]);
}
for(int j = len-2;j>=0;j--){
rightMax[j] = Math.max(rightMax[j+1], height[j]);
}
int sum = 0;
for(int i = 0;i<len;i++){
sum += Math.min(leftMax[i], rightMax[i]) - height[i];
}
return sum;
}