leetcode接雨水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.

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!

观察下就可以发现被水填满后的形状是先升后降的塔形,因此,先遍历一遍找到塔顶,然后分别从两边开始,往塔顶所在位置遍历,水位只会增高不会减小,且一直和最近遇到的最大高度持平,这样知道了实时水位,就可以边遍历边计算面积。看到这种先升后降的题,就应该形成反射,立马想到左右各遍历一边。于是可以写出方法一:

int trap(vector<int>& height) {
int n=height.size();
if(n<1)
return 0;
int maxindex=height[0];
int sum=0;
int maxva=-1;
for(int i=0;i<n;i++)
{
  if(height[i]>maxva)
  {
  maxva=height[i];
  maxindex=i;
  }
}

int tem=height[0];

for(int i=0;i<maxindex;i++)

{

if(tem>height[i])

sum+=tem-height[i];

else

tem=height[i];

}

tem=height[n-1];

for(int i=n-1;i>maxindex;i--)

{

if(tem>height[i])

sum+=tem-height[i];

else

tem=height[i];

}

return sum;

}

 

方法一遍历了三遍,那么可不可以只遍历一遍呢?由左右两边向中间挤压。

int trap(vector<int>& height) {
int n=height.size();
if(n<=2)
return 0;
int sum=0;

int left=0,right=n-1;
int maxleft=height[left],maxright=height[right];
while(left<right)
{

if(height[left]<height[right])
{
if(height[left]<maxleft)
{
sum+=maxleft-height[left++];

}
else
maxleft=height[left++];
}

else
{
if(height[right]<maxright)
{
sum+=maxright-height[right];
right--;
}
else
maxright=height[right--];
}

}

return sum;
}

 

想想,能不能用栈呢?单调栈。应该是可以的,稍后加上。

posted @ 2017-10-25 10:53  keep-thingking  阅读(321)  评论(0)    收藏  举报