Algorithm之路十一:Container With Most Water

题目:

给出一个整形数组,其中的元素为a1,a2,……an,现在在平面直角坐标系中作出点(i,ai),并与(i,0)连线,共形成n条线,现在任选两条线,可以个x轴形成一个容器,如果在这个容器中加水,如何选择n条线中的两条,才可以使得这两条线和x轴围成的容器装的水的面积更大。

Note:n大于1

举例:

1 8 6 2 5 4 8 3 7
最大面积为( a 9*(9-2)) = 49,

思路:

将题目理解之后,就明白了,题目实际上是要求找i,j,使得|min(ai - aj)*(i - j)|最大,最容易想到的就是暴力搜索,将所有情况的i,j组合都找到,但是显然这种方法简单易懂,肯定不是一个比较优秀的方法。

以下是一个时间复杂度为O(n)的策略:

具体的计算过程请看https://leetcode.com/problems/container-with-most-water/solution

我们知道一个容器能装多少水是由最短的板决定的,在题目中的这个二维的容器中,能装多少水,则看的较短的那个边,同时也要考虑底部的长度。

对于某个i,j,计算|(ai - aj)*(i - j)|,和maxarea比较,并更新maxarea的值,如果ai < aj,则i++,否则j--。

在比较aiaj的大小这一步,实际上相比于暴力搜索法省略掉了多步,在计算|(ai - aj)*(i - j)|时,假如ai < aj那么此时计算ai和aj-1,ai和aj-1,……ai和ai+1对应的直线之间的面积已经没有意义。原因如下:对于i + 1 <= m <= j - 1,若am > ai,此时容器的高度为ai,|(ai - am)*(i - m)|的值显然小于|(ai - aj)*(i - j)|的值,若am < ai,此时容器的高度为am,而m <= j - 1,|(ai - am)*(i - m)|的值仍然小于|(ai - aj)*(i - j)|的值,所以此时计算|(ai - am)*(i - m)|的值已经没有意义。所以这个时间复杂度为O(n)的策略比暴力搜索法省去了好多步骤,并且求得结果是正确的。

代码:

public class Container_With_Most_Water {
	
	public static int maxArea(int[] height)
	{
		int n = height.length;
		int start = 0;
		int end = n - 1;
		int maxarea = 0;
		while(end >= start)
		{
			maxarea = Math.max(maxarea, Math.abs((start - end)*(Math.min(height[start],height[end]))));
			if(height[start] > height[end])
				end--;
			else
				start++;
		}
		return maxarea;
    }
	public static void main(String[] args)
	{
		int[] height = {1,8,6,2,5,4,8,3,7};
		System.out.println(maxArea(height));
	}

时间复杂度:

只把数组遍历了一次,时间复杂度为O(n)。

空间复杂度:

O(1)。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值