一、分析
给出一个数组,储存墙的高度,输出能够装水最多的容量。
简而言之,就是求出令两堵墙尽可能高且距离尽可能远。
这破题做的我心态爆炸,明明是很简单的题,我却想了好久。
二、分析
1、我的思路(超时)
找出最小值,最小值对应的横坐标之差是确定的,最小值乘以横坐标之差就是容量。
每次找到一个最小值,下次就不能找它,若它是最前面或者最后面的,还要把横坐标之差更新。
维护两个变量start和end,start是“所有可选的值中横坐标最小的”,end则是最大的。
举例如下:
[1,8,6,2,5,4,8,3,7]
最小值为1,距离差为8-0=8,容量为8*1=8;
更新start=1,end=8;
最小值为2,距离差为3-1=2=或8-3=5,容量为5*2=10;
更新start=1,end=8;
最小值为3,距离差为7-1=6或8-7=1,容量为6*3=18;
。。。。。。
最后可以求出最大容量。
时间复杂度过大导致超时,关键在于求最小值需要nlogn,那么总时间就是n^2logn,无法忍受。
2、我的思路
想到快排中的算法。
对每个值,求出从离他最远的开始,第一个大于等于它的值的位置,则位置差乘这个值就是容积。
还是太麻烦。
3、较好思路
贪心算法。
既然容积等于长乘高,我们找高的最大值又不方便,那么不妨从长的最大值开始找。
维护两个变量start和end。
每次选start和end中较矮的当做高,求出高*(end-start)的值就是容积。
然后向内推进。如果start+1的高小于等于原来的高,那么start++,因为现在长变小了,你要是高还变小,那么容积肯定变小;
如果end-1的高小于等于原来的高,那么end--。
直到start>=end,退出。
三、总结
思路僵化,总想着对高度排序,完全忽略了可以由横坐标之差来进行贪心。愚蠢。
PS:代码如下:
class Solution {
public:
int maxArea(vector<int>& height) {
int ans=0;
int start=0,end=height.size()-1;
while(start<end)
{
int h=min(height[start],height[end]);
int temp=h*(end-start);
ans=max(temp,ans);
while(height[start]<=h&&start<end)
start++;
while(height[end]<=h&&start<end)
end--;
}
return ans;
}
};