leetcode Container With Most Water

今天在leetcode上做了一天,随便找了一些题大概做了10几个,感觉面试题真的很能体现个人能力啊。

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.

题目意思还是比较好懂的,O(n*n)的大家都能够想到了,很明显这肯定不是最好的答案。

我们定义i j为最大的容器区间。

我的第一个想法是简单剪枝,当我们遍历j的时候,为了求i,从0开始遍历遇到高度

height[i]>=height[j],时停止。因为最大容量计算公式为min(height[i],height[j])*(j-i)。这种想法虽然能减少一定的查找,但是时间复杂度不会变。最坏情况:递增的时候。


后来一想这个其实就是找合适区间,题目让我们想的合适区间应该是越大越好。因为要求容量最大。于是先把这个区间定义为最大 i=0,j=n-1; 如果这个最大的区间容量不是最大,那么这个区间子区间是相对较小的,我们只要找比区间边缘高度高的即可。


也就是说:当左边小于右边的时候,从左边开始找比左边缘更大的。

当右边小于左边,更新右边边缘,即找比右边缘更大的。

算法时间复杂度O(n);

class Solution {
public:
    int maxArea(vector<int> &height) {
        // IMPORTANT: Please reset any member data you declared, as
        // the same Solution instance will be reused for each test case.
    if(height.size()<2)
		return 0;
    int mmax=0;
   int l=0;
   int r=height.size()-1;
   while(l<r)
   {
       mmax=max(mmax,min(height[l],height[r])*(r-l));
       if(height[l]<=height[r])
         l++;
       else
        r--;
   }
	return mmax;    
  }
};

第二个版本是我更新边缘时,省一些求mmax次数。不知道为什么时间比上面的慢。

class Solution {
public:
    int maxArea(vector<int> &height) {
        // IMPORTANT: Please reset any member data you declared, as
        // the same Solution instance will be reused for each test case.
    if(height.size()<2)
		return 0;
   int mmax=0;
   int l=0;
   int r=height.size()-1;
   while(l<r)
   {
       mmax=max(mmax,min(height[l],height[r])*(r-l));
       if(height[l]<=height[r])
       {
           int t=l;
           while(t<r &&height[t]<=height[l])
                t++;
           l=t;
       }
       else
       {
           int t=r;
           while(l<t &&height[t]<=height[r])
                t--;
           r=t;
       }
   }
   return mmax;  
   }
};



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值