11. Container With Most Water

来源:互联网 发布:淘宝内部优惠券赚佣金 编辑:程序博客网 时间:2024/06/06 03:26

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 and n is at least 2.

这道题首先可以想到的思路是进行两重循环,寻找最大的容量,但是该方法时间复杂度为O(n2),不可避免的产生了超时,超时之后我想到这道题可能是利用动态规划,但是动态规划的方式没能找到转移关系,参考了一下题目的tag,发现这是一个两指针问题,于是将思路转移到两指针上面来,在这里粘贴出来自己参考的别人的解释,这样一来,这道题就迎刃而解了。

Easy Concise Java O(N) Solution with Proof and Explanation

AKA, the general idea to find some max is to go through all cases where max value can possibly occur and keep updating the max value. The efficiency of the scan depends on the size of cases you plan to scan.
To increase efficiency, all we need to do is to find a smart way of scan to cut off the useless cases and meanwhile 100% guarantee the max value can be reached through the rest of cases.

In this problem, the smart scan way is to set two pointers initialized at both ends of the array. Every time move the smaller value pointer to inner array. Then after the two pointers meet, all possible max cases have been scanned and the max situation is 100% reached somewhere in the scan. Following is a brief prove of this.

Given a1,a2,a3.....an as input array. Lets assume a10 and a20 are the max area situation. We need to prove that a10 can be reached by left pointer and during the time left pointer stays at a10, a20 can be reached by right pointer. That is to say, the core problem is to prove: when left pointer is at a10 and right pointer is at a21, the next move must be right pointer to a20.

Since we are always moving the pointer with the smaller value, i.e. if a10 > a21, we should move pointer at a21 to a20, as we hope. Why a10 >a21? Because if a21>a10, then area of a10 and a20 must be less than area of a10 and a21. Because the area of a10 and a21 is at least height[a10] * (21-10) while the area of a10 and a20 is at most height[a10] * (20-10). So there is a contradiction of assumption a10 and a20 has the max area. So, a10 must be greater than a21, then next move a21 has to be move to a20. The max cases must be reached.

代码如下:

public int maxArea(int[] height) {
        // 特殊情况处理
        if(height == null || height.length == 0){
            return 0;
        }
        int start = 0, end = height.length - 1;
        int maxContainer = 0;
        while(start < end){
            int volume = Math.min(height[start], height[end]) * (end - start);
            maxContainer = Math.max(volume, maxContainer);
            if(height[start] < height[end]){
                start++;
            }else{
                end--;
            }
        }
        return maxContainer;
    }


0 0
原创粉丝点击