Container With Most Water

Given n non-negative integers a1, a2, ..., an, where each represents a point at coordinate (i, ai). n vertical lines are drawn such that the two endpoints of line i is at (i, ai) and (i, 0). Find two lines, which together with x-axis forms a container, such that the container contains the most water.

Note: You may not slant the container.

方法一:穷举

超时。

方法二:

对题目的数学性质进行分析,发现:

1)对于最大容量的桶的左侧,设其横坐标为l。则al大于其左端任意一条竖线。

2)同理,对于最大桶的右侧,设其横坐标为r。则ar大于其右端任意一条竖线。

我就不证明了,用反证法即可。

这就对程序的实现提供了一条思路:每次从桶的一侧往中间收缩。收缩时,直到找到比当前高度更高的一条竖线时,才进行计算是否桶的容量有所增加。

采取这种两边往中间靠的方式,需要注意的有两点:

1)每次从当前较短的一条边进行往中间收缩。如果从较长的边进行收缩,则受制于另一条较短的边,新计算的容量总是会更小。

2)当收缩到左侧边横坐标等于右侧边横坐标时,循环结束。但为什么此时得出的最大容量就是最终的答案,它是否包含了所有需要考虑的情况?我没有进行严格的数学证明,只是程序通过了LeetCode平台的45个测试案例。

不过在csdn上看到一种解释:容积即面积,它受长和高的影响,当长度减小时候,高必须增长才有可能提升面积,所以我们从长度最长时开始递减,然后寻找更高的线来更新候补;

受到启发,这样来说服自己:这种方法从底边最长的长度开始,递减收缩至底边最短的长度,且在收缩过程中,容量是在不断的更大化。从底边的长度角度来看,其覆盖了所有的情况。

C语言代码如下:

<strong>int maxArea(int* height, int heightSize) {
	int left = 0, right = heightSize - 1;
	int volume = 0; 
	int tmpVolume;
	int k;
	while(left < right)
	{
		tmpVolume = (height[left] < height[right] ? height[left] : height[right]) * (right - left);
		volume = tmpVolume > volume ? tmpVolume : volume;
		if(height[left] < height[right])
		{
			k = left;
			while(height[k] <= height[left] && k < right)
				k++;
			left = k;
		}
		else
		{
			k = right;
			while(height[k] <= height[right] && k >left)
				k--;
			right = k;
		}
	}
	return volume;
};
</strong>


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值