您的位置:首页 > 移动开发

leetcode之路042 Trapping Rain Water

2015-10-26 21:12 309 查看
题目大意:给定n个非负的整数来代表高度图,每个条的宽度为1。计算下雨后它能装多少的水。

例:
0,1,0,2,1,0,1,3,2,1,2,1]
,
返回
6




思路:

1、从左往右进行以下操作,先找到一个从最左边开始的极大值点(此点高度大于左右两边的高度),即nums[i]>=nums[i-1]且nums[i]>nums[i+1]

2、在上述点之后查找高度值大于它的点,如果存在,则计算这两点组成的容器的蓄水量,并改变查找的起点进行思路1的操作。

3、如果不存在,则此点为它到数组末尾的最大值,此时,在此点后面查找最大高度点,计算此时的蓄水量。然后改变查找起点,进行思路1的操作。

4、数组遍历完毕,返回resu。

提交ac的代码如下,运行时间为16ms:

class Solution {
public:
int trap(vector<int>& height) {
int resu=0;
int i=1;
while(i<height.size())
{
while(i<height.size()&&height[i]>=height[i-1])++i;
int j=i;
while(j<height.size()&&height[j]<height[i-1])++j;
if(j!=height.size())
{
int m=0;
for(int k=i;k<j;++k)
{
m+=height[i-1]-height[k];
}
resu+=m;
i=j;
}
else
{
int n=max_element(height.begin()+i,height.end())-height.begin();
if(n>i)
{
int m=0;
for(int k=i;k<n;++k)
{
m+=height
-height[k];
}
resu+=m;
}
i=n+1;
}
}
return resu;
}
};


分析上述代码,1,在while大循环中的第二个while循环,当当前i所指结点高度为此点到数组末端的最大值时,会遍历往后的整个数组。因此会多次重复的扫描数组元素;2,用了max_element,此操作也要遍历数组,也会重复的扫描数组元素。因此这两点使得代码效率太低。时间复杂度最坏会达到O(n*n)。

在讨论区看到了O(n)的方法,很有借鉴意义,如下:

class Solution {
public:
int trap(int A[], int n) {
int left=0; int right=n-1;
int res=0;
int maxleft=0, maxright=0;
while(left<=right){
if(A[left]<=A[right]){
if(A[left]>=maxleft) maxleft=A[left];
else res+=maxleft-A[left];
left++;
}
else{
if(A[right]>=maxright) maxright= A[right];
else res+=maxright-A[right];
right--;
}
}
return res;
}
};
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: