原题是这样的:
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.
题目也比较容易理解,就是寻找两个a,使得这两个a的容积最大。
较简单的实现是O(n2)的,提交上去后,毫无悬念的TLE了。。。。。
于是寻找其他算法,感觉上是存在线性复杂度的算法的。刚开始的思想是从第一个开始扫描,记录start和end的值,然后记录下一个位置。每遍历一个位置,计算新的容积,但是这样由于长度不固定,会丢失很多解,所以结果错误。
无奈,参考了别人的算法。。。。。从两端开始扫描,两个位置记为i,j 。 代码如下:
public int maxArea(int[] height) { int i = 0 , j = height.length -1 ,mx = 0; while(i < j){ mx = Math.max(mx , (j - i) * Math.min(height[i],height[j])); if(height[i] > height[j]) j--; else i++; } return mx; }
首先,每一次移动 i 或者 j ,都会使长度L减一,这样可以在L固定的情况下进行计算。
若L固定,那么怎么得到当前长度下最大的容积呢?由公式可以看出
Volume(L) = (L) * min(height[i] , height[j]) (j - i = L)
所以容积是由两端的最小高度决定的。所以我们要找出在长度为L时,两端最小高度的最大值。
所以从L到L-1时,只有移动高度较小的那一端才有可能得到容积的最大值。
也就有了上面的算法。
PS:下次要自己思考,写出自己的算法。看别人的算法再证明实在是不爽。