非常有意思的一道题,关键是找到存水量的公式!同时应用DP
package Level4;
import java.util.Arrays;
/**
* Trapping Rain Water
*
* Given n non-negative integers representing an elevation map where the width of each bar is 1, compute how much water it is able to trap after raining.
For example,
Given [0,1,0,2,1,0,1,3,2,1,2,1], return 6.
http://www.leetcode.com/wp-content/uploads/2012/08/rainwatertrap.png
The above elevation map is represented by array [0,1,0,2,1,0,1,3,2,1,2,1]. In this case, 6 units of rain water (blue section) are being trapped. Thanks Marcos for contributing this image!
*
*/
public class S42 {
public static void main(String[] args) {
int[] A = {0,1,0,2,1,0,1,3,2,1,2,1};
// int[] A = {2,0,2};
System.out.println(trap(A));
}
// 关键是在于找到规律:
// 即第i块地方的存水量 = min(第i块左边最高的bar高度, 第i块右边最高的bar的高度) - 第i块地方bar的高度
// 例如图中,第5块地方的存水量 = min(2,3)-0 = 2
// 2为其左边最高的bar,即第3块地方的bar
// 3为其右边最高的bar,即第7块地方的bar,
// 0为其自身的bar高度
public static int trap(int[] A) {
if(A.length == 0){
return 0;
}
// 先用DP算出left, right数组
// left数组记录到当前i为止,左边最高的bar (包含i)
// right数组记录到当前i为止,右边最高的bar
int[] left = new int[A.length];
int[] right = new int[A.length];
left[0] = A[0];
for(int i=1; i<A.length; i++){
left[i] = Math.max(left[i-1], A[i]);
}
right[A.length-1] = A[A.length-1];
for(int i=A.length-2; i>=0; i--){
right[i] = Math.max(right[i+1], A[i]);
}
// System.out.println(Arrays.toString(left));
// System.out.println(Arrays.toString(right));
int sum = 0;
for(int i=1; i<A.length-1; i++){
sum += Math.min(left[i], right[i]) - A[i];
}
return sum;
}
}
public class Solution {
public int trap(int[] A) {
int len = A.length;
if(len < 3) {
return 0;
}
int area = 0;
int[] left = new int[len];
int[] right = new int[len];
left[0] = A[0];
right[len-1] = A[len-1];
for(int i=1; i<len-1; i++) {
left[i] = Math.max(left[i-1], A[i]);
}
for(int i=len-2; i>=0; i--) {
right[i] = Math.max(right[i+1], A[i]);
}
for(int i=0; i<len-1; i++) {
area += Math.min(left[i], right[i]) - A[i];
}
return area;
}
}
还有一些其他的解法,具体可以参考 http://blog.csdn.net/linhuanmars/article/details/20888505