[leetcode]Container With Most Water

来源:互联网 发布:知乎推荐无线蓝牙耳机 编辑:程序博客网 时间:2024/05/21 10:32

Container With Most Water

题意:

         在X轴上给定一些数,找出最大的可盛水的面积,这个面积是指两个数的较小的数*两个数之间的距离。比如第一个数和第三个数分别为5,7,所围盛水面积为Min(7,5)*(3-1)=10。

         暴力解法不说了,能不能过不清楚。

         O(N):

         参考http://www.cnblogs.com/lichen782/p/leetcode_Container_With_Most_Water.html

         但原文并没有给出算法正确性的证明。或者说我认为它的证明过程是错误的。

算法如下:一开始将左木板放在最左侧,右木板放在最右侧,当两木板不一样长时,将短木板向中心挪动,继续判断。直到左右木板重合。当两木板一样长时,随意将一块木板向中心挪动。

正确性分析:假设最优解是由两块不一样长的木板所构成,我们称之为最优木板。我们称我们不断尝试的木板为虚拟木板。由算法过程可知,虚拟木板的变化过程连续,必有一边先触及最优木板。1.如果先触及最优木板的短板,那么此刻一定是虚拟木板靠近最优长板的边向中心移动,若不然的话,意味着此时最优木板的短板比虚拟木板靠近最优长板的一边还要短,那么此时可以推出最优木版的短板+虚拟木板的靠近最有长板的一边组成一个比最有解更优的解,与假设矛盾。所以此时一定是虚拟模板靠近最优长板的一边向中心移动,直到把最优解试出来。2.如果先触及最优木板的长板,一定是靠近最优短板的虚拟木板向中心移动,否则目前的虚拟木板靠近短板的一边比最优短板更长,组成更优解。

当最优木板为两个相等高度的板时,当一边先触及时,一定是另一侧的虚拟木板向中心移动,因为另一侧的所有在最优木板之前的板全部小于最优木板的高度,否则会组成更有解。

public class Solution141 {

   public int maxArea(int[] height) {

       int n=height.length;

       if ((n==0)||(n==1)){

                return 0;

       }

       int left=0;

       int right=n-1;

       int ans=0;

       while(true){

                if (left>=right){

                          break;

                }

                if (Math.min(height[left],height[right])*(right-left)>ans){

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

                }

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

                          left++;

                }else{

                          right--;

                }

       }

       return ans;

    }

}


0 0
原创粉丝点击