给定一个长度为 n 的整数数组 height 。有 n 条垂线,第 i 条线的两个端点是 (i, 0) 和 (i, height[i]) 。
找出其中的两条线,使得它们与 x 轴共同构成的容器可以容纳最多的水。
返回容器可以储存的最大水量。
乍一看几乎没啥思路,不过把题目抽象一下,不就是求一个长方形的面积吗?而且这个长方体的长和高都是动态的,且高是左右两边最小的那一个。
那么最粗暴的解法就有了,从nums[0]开始算,求nums[0]~nums[i]组成的面积,长是i-0,高是min{nums[0],nums[i]},i表示数组下标
之后从num[1],nums[2].......计算,最后找到最大的那个就行
不过这样对于算法肯定是不行的,因为要算的面积太多了。
所以思考一下怎么减少计算量??长度每次都会递增1,高度不确定?
想一下,找个数组里面最小的数,那么它组成的所有长方形的高肯定就是它本身,因此找离它最远的那个数组成长方形,这就是它的最大容量。
之后找第二小的数(此时就不用考虑比和它小的数组成的长方形的面积了),找第二小的数的最大面积长方形,
之后找第三找第四.......找到最大数后停止,计算量好像减少了很多。
这么看来就很清晰了,只要对数组内的每个数找比它高且离它最远的那个就好了,之后选里面最大的那个。
class Solution { public: int maxArea(vector<int>& height) { int max=0; for(int i=0;i<height.size();i++) { int length=0; for(int j=0;j<height.size();j++) { if(j!=i) { if(height[j]>height[i]||height[j]==height[i]) { int length_temp=abs(j-i); length=length>length_temp?length:length_temp; } } } int max_temp=length*height[i]; max=max>max_temp?max:max_temp; } return max; } };
超时!!果然O(N2)根本不行。 不过优化一下试试:
class Solution { public: int maxArea(vector<int>& height) { int max=0; for(int i=0;i<height.size();i++) { int length=0; if(i<height.size()/2) { for(int j=height.size()-1;j>0;j--) { if(height[j]>height[i]||height[j]==height[i]) { length=abs(j-i);break; } } } else { for(int j=0;j<height.size();j++) { if(height[j]>height[i]||height[j]==height[i]) { length=abs(j-i);break; } } } max=max>length*height[i]?max:length*height[i]; } return max; } };
勉强能跑,因为优化了寻找最长边的循环条件,前一半的数从末尾找,后一半的数从前面找;
但明显这样的解法不好。而且题目是关于双指针的,怎么用双指针达成O(N)的复杂度呢??
上面我是找每个高对应的最长边求最大面积,要找两次,先找高,再找边。反过来,我直接从最长的边开始找,直接就确定了高不是吗?这不就只用遍历一次吗?
思考一下,最长的边肯定是首尾这两个数组成的,用begin和end标记下。begin=0;end=n;(n表示数组的长度-1,end-begin就是边长) ;
它的高度是这俩小标对应的最小的那个数,所以面积也确定了,之后缩小边(因为边只能1单位1单位的减少)再找高。
问题是,从左侧还是右侧的地方往里缩小呢??
根据题目,是要找最大的面积,我期望缩小后的这个面积是比原来大的,假如我从高处缩小,肯定不行,期望面积在减小,不行,所以只能从低处往里缩小,这样期望面积才有可能变大。
如此一来,题解就有了。
代码如下:
class Solution { public: int maxArea(vector<int>& height) { int begin=0; int end=height.size()-1; int max=0; int l=0; int h=0; while(begin<end) { l=end-begin; if(height[begin]<height[end]||height[begin]==height[end]) { h=height[begin]; } else { h=height[end]; } max=max>l*h?max:l*h; if(h==height[begin]) { begin++; } else end--; } return max; } };
标签:容器,begin,temp,盛水,int,max,height,length From: https://www.cnblogs.com/HaveFunnyAnyone/p/17490038.html