(Java)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.


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!


这道题想了蛮长时间,受到了Tags里two points的启发。思路是这样的:

首先,进行预处理,去掉两侧不能储水的部分

然后,总左向右遍历,每当V字形储水结构的右边比左边高的时候,就计算一次当前V能储存多少水,因为当V字形右边比左边高的时候不会受到后面的影响,直到结束,记下已计算的最右边的节点序号。

再次,从右向左遍历到上述节点序号,每当V字形储水结构的左边比右边高的时候,就计算一次能存储多少水,因为此时不会受到左边的影响。完毕。代码如下:

public class Solution {
    public int trap(int[] height) {
    	int start = 0;
    	int end = 0;
    	int len = height.length;
    	if(len < 3)
    		return 0;
    	for(int i = 1; i < len ; i++){
    		if(height[i] >= height[i-1]){
    			continue;
    		}else{
    			start = i-1;
    			break;
    		}
    	}
    	
    	for(int i = len-2; i >= 0; i--){
    		if(height[i] >= height[i+1]){
    			continue;
    		}else{
    			end = i+1;
    			break;
    		}
    	}
    	
    	int leftHeight = height[start];
    	int rightHeight = height[end];
    	int leftNum = start;
    	int rightNum = end;
    	int sum = 0;
    	for(int i = start+1; i <= end; i++){
    		if(height[i] < height[leftNum]){
    			continue;
    		}else{
    			sum += calEach(height, leftHeight, height[i], leftNum, i);
    			leftNum = i;
    			leftHeight = height[i];
    		}
    	}
    	
    	for(int i = end-1; i >= leftNum; i--){
    		if(height[i] < height[rightNum]){
    			continue;
    		}else{
    			sum += calEach(height, height[i], rightHeight, i, rightNum);
    			rightNum = i;
    			rightHeight = height[i];
    		}
    	}
        return sum;
    }
    
    private int calEach(int[] height, int leftHeight, int rightHeight, int leftNum, int rightNum){
    	int shorter = leftHeight < rightHeight ? leftHeight : rightHeight;
    	int sum = 0;
    	for(int i = leftNum ; i <= rightNum; i++){
    		if(height[i] < shorter){
    			sum += (shorter - height[i]);
    		}
    	}
    	return sum;
    }
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值