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;
}
想想,能不能用栈呢?单调栈。应该是可以的,稍后加上。

浙公网安备 33010602011771号