11-Container with Most Water-把数组看成装水的容器

给定n个非负整数a1,a2,...,an,其中每个代表坐标(i,ai)处的一个点。绘制n条垂直线,使得线i的两个端点处于(i,ai)和(i,0)处。找到两条线,它们与x轴一起形成一个容器,使得容器包含最多的水。容器无法倾斜,n至少为2。

木桶效应,一个水桶装多少水取决于最短的木板,这是隐含条件。所以我们的最终运算结果应该是:

(high-low)*Math.min( height[low], height[high] ),即底部的长度,乘以两条边中较短一条的长度。

暴力搜索,从头到尾算出每一个组合的容积并进行比较。这种方法非常直观容易,但是明显效率很低,时间复杂度达到了n2

解决问题嘛,咱们还是尽可能想出最好的办法。水桶的壁长总在变化不太好控制,至少我们知道底盘越大,存的水总归越多。所以考虑在初始化的时候,给数组的首位和末尾各设置一个桶壁,从数组的上下界开始计算,然后逐渐收拢桶壁。

收拢的条件又是什么呢?在木桶底部不断缩小的前提下,感觉上舍弃当前两壁中较短的一个,才更有可能获得容积上的增益(在文末提出一点疑惑)。于是我们以当前两桶壁的比较为标准,舍弃较短的一面,并让这一面向内收拢。

贴代码:

public int maxArea(int[] height) {
        if(height.length<2) return 0;
        int low = 0, high = height.length-1;
        int max = 0;
        while(low<high) {
        	max = Math.max( max , (high-low) * Math.min(height[low], height[high]) );
        	if(height[low] < height[high]) {
        		low++;
        	}else high--;
        }
        return max;
}


在思考算法本身的时候,感觉到舍弃较长桶壁也是有可能得到增益,但是写程序就尽可能按照逻辑来。至于为什么一定能算出最优解,其实我也没想明白,但是在验算的时候设想了几种场景,按照这个算法都能得出正确结果。可能是数学上的某种逻辑吧?欢迎明白这个原理的朋友解释指正~


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值