LeetCode------Container With Most Water

原题是这样的:

Given n non-negative integers a1a2, ..., an, where each represents a point at coordinate (iai). n vertical lines are drawn such that the two endpoints of line i is at (iai) 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:下次要自己思考,写出自己的算法。看别人的算法再证明实在是不爽。难过



你可能感兴趣的:(LeetCode,算法,遍历)