zoukankan      html  css  js  c++  java
  • 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 }
  • 相关阅读:
    基于协同过滤的个性化Web推荐
    自动推荐系统效果为什么不好
    基于模糊聚类和协同过滤的混合推荐系统
    海量数据处理之蓄水池抽样算法
    心灵启发--不羡慕别人的生活
    ubuntu安装软件整理
    Hadoop系列
    网页返回错误编号含义整理
    找出单链表的中间位置指针
    【python爬虫】根据查询词爬取网站返回结果
  • 原文地址:https://www.cnblogs.com/maydow/p/4627351.html
Copyright © 2011-2022 走看看