Container With Most Water容器盛水

33 篇文章 0 订阅
14 篇文章 0 订阅

11. 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坐标,数组元素代表相应的y坐标值。

从y坐标向x轴引垂线,求两条垂线,使得他们围成的容器装水最多。

双层for循环那种暴力解法肯定不会满足时间要求。所以尽量选择时间复杂度为O(n)的解法。

解题思路:首尾两个指针分别往中间移动,由于求装水最多,所以求area时,

只考虑对比的两条垂线中最短的那条就可以,每次都记录相应的area。

最后返回最大的area即可。首先想到了下面的第一个方法,但是这个方法还是超过了时间限制。如下:

public class Solution {
    public int maxArea(int[] height) {
       if (height.length<2) {
			return 0;
		}
		int start = 0;
		int end = height.length-1;
		int area = 0;
		while (start < end) {
			int v  = Math.min(height[start], height[end])*(end-start);
			area =Math.max(area,v);
					
			if (height[start]<height[end]) {
				start++;
			}else {
				end--;
			}
		}		
		return area;   
    }
}


然后,仔细考虑,发现,其实在移动的时候,以start为例,

当移动start时,它右边的值如果比start所在位置的元素小的时候,可以不用计算了,

因为它不会在比start位置的元素求的area大。

end方向同理。继续优化上面的方法得到下面的代码:

public class Solution {
    public int maxArea(int[] height) {
      if (height.length<2) {
			return 0;
		}
		int start = 0;
		int end = height.length-1;
		int area = 0;
		while (start < end) {
			int v  = Math.min(height[start], height[end])*(end-start);
			area =Math.max(area,v);
					
			if (height[start]<height[end]) {
				int k = start;
				while (k < end && height[k]<=height[start]) {//只要start右边的元素比start所在位置的元素小
					k++;			//就可以不用在算面积,因为不会比start所在位置的元素求出的面积大
				}
				start = k;
			}else {
				int k = end;
				while (k > start && height[k]<=height[end]) {//只要end左边的元素比end所在位置的元素小
					k--;			//就可以不用在算面积,因为不会比end所在位置的元素求出的面积大
				}
				end=k;
			}
		}		
		return area;       
    }
}



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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值