Trapping Rain Water 求存水量 @LeetCode

来源:互联网 发布:可变数据排版 编辑:程序博客网 时间:2024/04/30 21:03

非常有意思的一道题,关键是找到存水量的公式!同时应用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.pngThe 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为止,右边最高的barint[] 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