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.

翻译过来就是找到两条线,使这两条线和x轴组成的容器能够存放的水最多。

首先想到的方法是采用遍历

1、时间复杂度o(n^2)

  对所有可能的情况进行遍历,找出容积最大的情况

  

         int area=0,maxArea=0;

        int len=height.length;

        if(len<=1)

            return 0;

        for(int i=0;i<len;i++)

        {

            for(int j=i+1;j<len;j++)

            {

                int min=Math.min(height[i], height[j]);

                area=min*(j-i);

                if(area>maxArea)

                    maxArea=area;

            }

        }

        return maxArea;

2、时间复杂度O(n)

  这种方法采用两个指示数,分别从左和右向中间靠拢找到最大的面积。

  当height[left]<height[right]时,left++;当height[right]<height[left],right--.

  现在问题的关键是要证明解法的正确性!

  首先为什么要让小的竖线向内移,因为area=(right-left)*min(height[left],height[right]),

  设left是小的竖线,此时area'=(right-left)*height[left];

  假如让right向内移即right--,设为right',而新的min(height[left],height[right'])<=height[left],同时right'-left<right-left。这样新的area必然会小于之前的area.

  为了获取更大的面积,只能让left++,即小的左移。

  其次,为什么不让left--呢?即是否存在一个数m,当m<left时,使得面积大于当前最大面积C。

  这里会用到数学上的一条性质:a>=min(a,b)。

  假设存在这样的一个数m,使得面积大于C,即rearRM=(right-m)*min(height[right],height[m])>C。

  由规则所知,从m移动到left,肯定是在right或者right的右边存在一个一个数k,使得height[k]>height[m]。

  即之前存在areaKM=(k-m)*min(height[k],height[m])<=C,而areaKM=(k-m)*height[m].

  而(k-m)>(right-m),height[m]>=min(height[m],height[right])  ==>  areaKM>areaRM   ==>     C>=areaKM>areaRM>C。

  出现矛盾,即不存在这样的m。

  同理,在right的右侧是否也存在这样的一个数呢?答案是否定的。

  

 1 public class Solution {

 2     public int maxArea(int[] height) {

 3                int maxArea=0,area=0;

 4         int len=height.length;

 5         int left=0,right=len-1;

 6         while(left<right)

 7         {

 8             area=(right-left)*Math.min(height[left], height[right]);

 9             if(area>maxArea)

10                 maxArea=area;

11             if(height[left]<height[right])

12                 left++;

13             else {

14                 right--;

15             }

16         }

17         return maxArea;

18     }

19 }

 

你可能感兴趣的:(LeetCode)