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;
    }



你可能感兴趣的:(LeetCode)