[Leetcode] 11. Container With Most Water

Description:
Given n non-negative integers a1, a2, …, an, where each represents a point at coordinate (i, ai). n vertical lines are drawn such that the two endpoints of line i is at (i, ai) 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.

Language: C++

解法一:Time Limit Exceeded
暴力解法,遍历所有i,j可能的组合,然后依次判断是否结果大于当前最大容量volume。对于数据量庞大(如15000)时超时Time Limit Exceeded不能AC。
Time: O(n2) O ( n 2 )
Space: O(1) O ( 1 )

class Solution {
public:
    int maxArea(vector<int>& height) {

        assert(height.size() > 1);

        int maxwater = 0, i = 0, j = height.size()-1;

        for(int i = 0; i < height.size()-1; i++){
            for(int j = i+1; j < height.size(); j++){

                int h = height[i] > height[j] ? height[j] : height[i];

                if(h * (j - i) > maxwater)
                    maxwater = h * (j - i);
           }
        }
        return maxwater;
    }
};

解法二:AC
基本思想:对撞指针。
思路:这道题是可以用对撞指针去做的,不确定的话就画个图试试。问题要求的是最大的volume,如果不好理解,可以先画个图,看看具体是怎么变动的。i从头开始,j从尾开始,比较height[i]和height[j],较小的那个(短板)决定了我们能装多少水,此时高的板再高也没有用,水量已经被短板决定,而我们是为了找最大的volume,所以继续找一个板大于当前短板。
如height[i] < height[j], 此时挪动j只可能找到比当前水量更少的水量(如果j板更大或相等,最小高度都是height[i]不变,由于距离更近了,此时只可能更小; 如果找到一个比height[i]更小的板,那么只可能更小了),因此我们要挪动的是i,使得另一个height[i]大于当前height[i],来得到更多的水量。

另:liuyubobobo老师的解答:
“我们可以形象的理解一下初始的情况是底边最长的情况在这样的情况下如果存在容积更大的容器底边肯定会缩小。此时唯一的方法就是增加高度。我们每次都尝试舍弃两边最短的那个高度来看新的高度能不能构建出容积更大的容器出来”

         |           |
         |  |     |  |     |
      |  |  |  |  |  |  |  |
      ----------------------
start i                    j  
         i                 j
         i              j
         i           j
         i        j    
         i     j
         i  j
 end     ij      

Time: O(n) O ( n )
Space: O(1) O ( 1 )

class Solution {
public:
    int maxArea(vector<int>& height) {

        assert(height.size() > 1);

        int maxwater = 0, i = 0, j = height.size()-1;

        while(i < j){

             int h = height[i] > height[j] ? height[j] : height[i];      
             if(h * (j - i) > maxwater)
                maxwater = h * (j - i);

            if(height[i] < height[j])
                i++;
            else
                j--;           
        }      
        return maxwater;
    }
};
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值