LeetCode #46Trapping 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.
所能组成的用来积水的块,每一块需要两个板作为边界。
当计算两个板之间的积水'面积'时,需要去除山的面积。。
主要问题有二:
1.确定能积水的各个板
2.每个板对所能积的水
对于问题1:
    分类:以左边的板为瓶颈:“短版”
          以右边的板为瓶颈:“短版”
    如果是以左边的板为边界,则右边的第一块板高不低于前者的作为右边界
   
    从左一开始,每次右边界作为下次的左边界(左边的板)
对于问题2:
    在这两块板之间,记所有底分别为d1,d2,***,dn
                    记ai = left - di
                    对中间的所有进行求和,其和即为该部分的积水
pre: a list of int for height
post: the rain water
algorithm:
   if height.size < 2 :
 return 0
   left <- height[0]
   sum <- 0
  
   //left as the short board
   v <- 0
   for i <- 1 to height.size-1:
      if height[i] >= left:
         left <- height[i]
         sum += v
         v <- 0
      else:
         v = v + (left-height[i])
   //right as the short board
   right <- height[-1]  , v <- 0
   for i <- height.size-1 to 0:
      if height[i] > right:
         right <- height[i]
         sum += v
         v <- 0
      else:
         v = v + (right-height[i])
    return sum
  
 时间复杂度: O(N)
注意:
    对于左边板和右边板同高的,只需要记录一次
python实现
def trap( height):
    if( len(height) < 2 ):
        return 0
    left = height[0]
    ans = 0
    v = 0
    for i in range(1,len(height) ):
        if height[i] >= left :
            left = height[i]
            ans += v
            v = 0
        else :
            v += left-height[i]

    #right
    right = height[-1]
    v = 0
    i = len(height)-1
    while i >= 0 :
        if height[i] > right :
            right = height[i]
            ans += v
            v = 0
        else :
            v += right-height[i]
        i -= 1
    return ans



c++实现
int trap( vector<int>& height ){
	int left = height[0] , sum = 0 , v = 0 ;
	// left as the short board && maybe equal
	for ( int i = 1 ; i < height.size() ; i ++ ){
		if ( height[i] >= left ){
			left = height[i] ;
			sum += v ;
			v = 0 ;
		}else {
			v += left-height[i] ;
		}
	}
	//right
	int right = height[height.size()-1] ;
	v = 0 ;
	for ( int i = height.size()-1 ; i >= 0 ; i -- ){
		if( height[i] > right ){
			right = height[i] ;
			sum += v ;
			v = 0 ;
		}else {
			v += right-height[i] ;
		}
	}
	return sum ;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值