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 }
原文地址:https://www.cnblogs.com/maydow/p/4627351.html