Trapping Rain Water [hard]

以 下 题 目 网 址 来 源 https://leetcode.com/

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.

  

  • Total Accepted: 100558
  • Total Submissions: 281963
  • Difficulty: Hard
  • Contributors: Admin

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!



分析题意可理解为求山谷之间的积水容量,所以我的思路是从左往右依次寻找山谷,定义山谷的左右两个山峰,左峰(left)先取第一个海拔不为零的山峰,根据木桶效应找到与之对应的右峰(right),这里分为两种情况,第一种是左锋已经是最高峰,所以右峰需要是低于左锋的最高峰,为了方便计算,当有多个等高的右峰时,取最右边的;第二种是左锋不是最高峰,所以在找右峰的同时需要保证右峰的海拔刚好大于等于左锋,在往右遍历其他山峰时若找到第一个大于左锋的山峰就停止。找到右峰后计算两峰之间的最大容积在扣去中间夹杂的小山峰,便得到一个山谷的积水容积,然后将前一个山谷的右峰作为左锋,继续寻找左锋。以此类推,直到找不到右峰为止,即右峰的值为默认值(right==0)。


代码如下:

int trap(vector<int>& height) {
	int i=0;
    	if( height.empty() ) return 0;
    	while( height[i]==0 ) i++;
    	int left,right,sum=0;
        for(int j=i; j<height.size();){
    	    int s=1;
            left=j,right=0;
    	    if( height[j+1] >= height[j] ) ;
            else{
                 int wide=1,h=0;
		 int temp=height[j+1];
  	 	 for(int k=j+1; k<height.size(); k++){
		    if( height[k] >= temp ){
	      	       temp=height[k];
	  	       right=k;
	               if( height[k] > height[left] ) break;
	            }
    		 }
	    	 if( right==0 ) break;
		 wide=right-left-1;
		 h=height[left] <= height[right] ? height[left] : height[right] ;
    		 int bar=0;
	    	 for(int r=left+1; r<right; r++){
		     bar+=height[r];
	         }
    		 sum+=h*wide-bar;
	    	 s=wide+1;
//	         cout<<"left= "<<left <<endl;
//		 cout<<"right= "<<right <<endl;
//	         cout<<"wide= "<<wide <<endl;
//	         cout<<"h= "<<h <<endl;
//	         cout<<"bar= "<<bar <<endl;
//		 cout<<"sum= "<<sum <<endl;
//         	 cout<<endl;
	    }
	    j+=s;
	}
        return sum;
    }


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值