Trapping Rain Water 求存水量 @LeetCode

非常有意思的一道题,关键是找到存水量的公式!同时应用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



你可能感兴趣的:(Trapping Rain Water 求存水量 @LeetCode)