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!
解题思路:
求不规则容器能存储水的体积。
方法一:
先找到最高的横板,然后从左向此横板遍历,如果存在A【i】.max(A[0]~A[i-1])>A[i],则max(A[0]~A[i-1])-A[i]就是在A[i]上的储水量。相同方法,再从右像横板遍历一次即可。代码如下:
class Solution {
public:
int maxheight(int left,int right,vector<int> height)
{
int fmax=left;
for(int i=left;i<right;i++)
{
if(height[i]>height[fmax])
fmax=i;
}
return fmax;
}
int trap(vector<int>& height) {
if(height.size()<3) return 0;
int res=0;
int left=0;
int firstmax=maxheight(left,height.size(),height);
for(int i=left;i<firstmax;i++)
{
int partMax=maxheight(left,i,height);
if(height[partMax]>=height[i])
{
res+=height[partMax]-height[i];
}
}
for(int i=height.size()-1;i>firstmax;i--)
{
int partMax=maxheight(i,height.size(),height);
if(height[partMax]>=height[i])
{
res+=height[partMax]-height[i];
}
}
return res;
}
};
方法二:
第一种方法循环太多,时间复杂度大。这里使用两边往中间遍历,记录当前第二高点cur_max,然后利用这个第二高点减去当前历经的柱子,剩下就装水容量了。
为什么是第二高点?因为两边比较,最高的点不用动,只移动第二高点。代码如下:
class Solution {
public:
int trap(vector<int>& height) {
if(height.size()<3) return 0;
int res=0;
int left=0;
int right=height.size()-1;
int cur_max=0;
while(left<right)
{
if(height[left]<height[right])
{
cur_max=(height[left]>cur_max)?height[left]:cur_max;
res+=cur_max-height[left];
left++;
}
else
{
cur_max=height[right]>cur_max?height[right]:cur_max;
res+=cur_max-height[right];
right--;
}
}
return res;
}
};