*LeetCode--42. 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.
问题大意:给出一个长为n的整型数组,每一个数字代表木块的高度。计算这些木块总共能容下多少水
tags: Array, Two pointers

方法:
首先找到最高的,
然后从左往最高处扫,碰到一个数A[i],先看A[0,...,i-1]最高的是否高过A[i],如果是,则A[i]上的水的体积为max(A[0...i-1])-A[i],否则为0并且更新最大值
然后从右往最高处再进行一次相同的操作。
这张图更加直观: 每次相当于求的是上方蓝色竖状条的长度。 
原图来自:http://www.xuebuyuan.com/1586534.html
代码:
public static int trap(int[] height) { int len = height.length; if(len==0) return 0; int maxindex = 0; //先找到最高的位置 for (int i = 1; i < len; i++) { if (height[i] > height[maxindex]) maxindex = i; } int vwater = 0;//指示水的总体积 int sechigh = height[0]; //保存次高的高度,也就是maxindex左侧最高的 for(int i = 1 ; i < maxindex ; i++){ if(height[i] > sechigh ) //若当前高度大于左侧最高的,更新最高高度(此高度不可能存水) sechigh = height[i]; else //高度小于左侧最高,在水的总体积上加上当前竖条部分能存水的体积 vwater += sechigh - height[i]; } //对右侧进行相同操作 sechigh = height[len-1]; for(int i = len-2 ; i > maxindex ; i--){ if(height[i] > sechigh ) sechigh = height[i]; else vwater += sechigh - height[i]; } return vwater; }
我自己的方法:超时了(时间复杂度O(n^2))。每次求的是横向条的体积。start表示当前高度横向段的起始位置,end表示当前高度横向段的结束位置。
public static int trap(int[] height) { int len = height.length; if(len==0||len==1||len==2) return 0; int maxh = height[0]; for (int i = 1; i < len; i++) { if (height[i] > maxh) maxh = height[i]; } int start = 0; int end = 0; int vwater = 0; for (int h = 1; h <= maxh; h++) { int i = 0; while (i < len-1) { start = 0; while (i < len-1) { if (height[i] >= h && height[i + 1] < h) { start = i; break; } i++; } i++; end = start + 1; while (i < len) { if (height[i] >= h && height[i - 1] < h) { end = i; break; } i++; } vwater += (end - start - 1); System.out.println(start+" "+end+" "+h+" v:"+ vwater); } } return vwater; }

浙公网安备 33010602011771号