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.每个板对所能积的水
对于问题1:
分类:以左边的板为瓶颈:“短版”
以右边的板为瓶颈:“短版”
如果是以左边的板为边界,则右边的第一块板高不低于前者的作为右边界
从左一开始,每次右边界作为下次的左边界(左边的板)
分类:以左边的板为瓶颈:“短版”
以右边的板为瓶颈:“短版”
如果是以左边的板为边界,则右边的第一块板高不低于前者的作为右边界
从左一开始,每次右边界作为下次的左边界(左边的板)
对于问题2:
在这两块板之间,记所有底分别为d1,d2,***,dn
记ai = left - di
对中间的所有进行求和,其和即为该部分的积水
在这两块板之间,记所有底分别为d1,d2,***,dn
记ai = left - di
对中间的所有进行求和,其和即为该部分的积水
pre: a list of int for height
post: the rain water
algorithm:
if height.size < 2 :
return 0
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])
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
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])
if height[i] > right:
right <- height[i]
sum += v
v <- 0
else:
v = v + (right-height[i])
return sum
时间复杂度: O(N)
时间复杂度: 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 ;
}