Leetcode: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!

刚开始做错了,先找下降的,再找上升的,代码如下

class Solution {
public:
    int trap(int A[], int n) {
        // Note: The Solution object is instantiated only once and is reused by each test case.
         if(NULL==A || n<=1)
            return 0;
        int beg=0,end=1,change=-1,max=0;
        int result = 0;
        while(beg<n)
        {
            while(end<n && A[end-1]>A[end]) //is down
            {
                ++end;  
            }
            if(end<=n && end-beg>1)//is down
            {
                max = A[beg];
                change = end-1; 
                //up
                int tmp = 0;
                while(end<n && A[end-1]<=A[end] )//is up
                {
                    ++end;  
                }
                if(end-change==1)//not up
                {
                    beg = end-1;
                    continue;
                }
                if(end-1<n && max>A[end-1])
                {
                    max = A[end-1]; 
                }
                //down
                for(int j=beg+1; j<end ; ++j)
                {
                    if(A[j]<max)
                        tmp += max-A[j];    
                }
                result += tmp;
                beg = end-1;
                continue;
            }
            beg = end;
            ++end;
        }
        return result;
    }
};

Input:[4,2,0,3,2,5]
Output:5
Expected:9
错误,后来恍然大悟,如果两头构成最大的显然是错的,真是傻逼了。。。

分析:对某个值A[i]来说,能trapped的最多的water取决于在i之前最高的值leftMostHeight[i]和在i右边的最高的值rightMostHeight[i](均不包含自身)。

如果min(left,right) > A[i],那么在i这个位置上能trapped的water就是min(left,right) – A[i]。

有了这个想法就好办了,第一遍从左到右计算数组leftMostHeight,第二遍从右到左计算rightMostHeight。时间复杂度是O(n)。

int trap(int A[], int n) {
        // Note: The Solution object is instantiated only once.
        if(A==NULL || n<1)return 0;
    	
		int maxheight = 0;
		vector<int> leftMostHeight(n);
		for(int i =0; i<n;i++)
		{
			leftMostHeight[i]=maxheight;
			maxheight = maxheight > A[i] ? maxheight : A[i];
		}

		maxheight = 0;
		vector<int> rightMostHeight(n);
		for(int i =n-1;i>=0;i--)
		{
			rightMostHeight[i] = maxheight;
			maxheight = maxheight > A[i] ? maxheight : A[i];
		}

		int water = 0;
		for(int i =0; i < n; i++)
		{
			int high = min(leftMostHeight[i],rightMostHeight[i])-A[i];
			if(high>0)
				water += high;
		}
		return water;
    }



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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值