您的位置:首页 > 移动开发

Leetcode42 Trapping Rain Water

2015-08-06 10:18 435 查看

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.



Solution1

扫描两遍数组,第一遍从左到右扫描,记录扫到当前位置的左边最大值。第二遍从右边扫描到左边,记录扫到当前位置的右边最大值,并将这二者最大值的最小值记录在一个新的数组里,那么所储存的水量便是该最小值减去当前的高度。代码如下:

public class Solution {
public int trap(int[] height) {
int[] max = new int[height.length];
int result = 0;
for(int i=0,highest=0;i<height.length;i++){//从左到右扫
highest = Math.max(highest,height[i]);//记录左边最大值
max[i] = highest;
}
for(int i=height.length-1,highest=0;i>=0;i--){//从右到左
highest = Math.max(highest,height[i]);//记录右边最大值
max[i] = Math.min(highest,max[i]);//两边最大值的最小值
result += max[i] - height[i];//两边最大值的最小值减去当前高度便是储存水量
}
return result;
}
}


Solution2

解法一简单易懂,但是缺点在于需要O(N)的空间复杂度,并且需要扫描两遍数组。实际上可以将两边扫面数组放在一次扫描当中实现,但是需要两个指针,每次移动较短边,因为是较短边决定了两条边中间所能够储存的水量。

public class Solution {
public int trap(int[] height) {
int result = 0;
for(int i=0,j=height.length-1,left=0,right=0;i<j;){
if(height[i]<height[j]){
left = Math.max(left,height[i]);//记录左边的最大值
result += left - height[i++];
}else{
right = Math.max(right,height[j]);
result += right - height[j--];
}
}
return result;
}
}


Solution3

将解法二用更简洁的语言表示如下(理解起来稍困难,可以对应着题目当中的图来一步一步理解):

public class Solution {
public int trap(int[] height) {
int result = 0;
for(int i=0,j=height.length-1,max=0;i<j;){
max = Math.max(max,height[i]<height[j]?height[i++]:height[j--]);
result += max - Math.min(max,Math.min(height[i],height[j]));
}
return result;
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  leetcode