您的位置:首页 > 大数据 > 人工智能

11.Container With Most Water

2016-03-24 21:44 302 查看

Container With Most Water

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.

在平面直角坐标系中,vector 中的下标构成了x轴上的点,下标对应的数字构成了y轴上的点,从(x,0)到(x, y)练成一条线,于是整个vector中的数据构成了一条条的数值线段。我们从这些线段中挑出两条线段,以两条线段之间的直线距离为宽,以两条竖直线段中较低一条线的高度作为高,形成一个水箱,求这些线段组成的水箱可容纳的最大面积是多少?

解法介绍

第一眼就想到了O(n*n)的暴力算法,果断放弃了这个算法,即使是去面试,这种算法肯定要被鄙视。于是我仔细想着有没有nlogn或者线性复杂度的方法,但是我想了很久,一直没有想到更好的办法。最后去百度了一下,看了别人的方法,豁然开朗,原来如此。

假设我们挑选了两条线段,高度分别为hi和hj,再假设hi是较矮的一条。hi所在的下标为i,hj所在的下标为j,不妨设j>i,于是这两条线段组成的水箱的面积为:

S = hi*(j-i),

假设S就是我们要求的最大面积,我们可以肯定下标j之后没有高度大于v[j]的线段,因为如果存在v[x]=hx>hj,那么S = hi*(x-i),很显然,x-i>j-i,同理可以证明,下标i的左边也没有比hi高的线段。

那么,知道这个有什么卵用呢?。。囧

我们从数组两边开始取数,此时形成的待选水箱长度是最长的,左边下标从i开始,右边下标从j开始,对应高度分别为hi和hj,再次假设hi小于hj,于是此时S=hi

X(j-i),然后开始挑选下一跳待选线段,那么问题来了,选择++i开始–j呢?

如果选择++i,优先挪动高度较低的线段的下标,假设下标变为k,对应高度为hk,有两种情况,hk大于等于hj, 面积S1’ = hj X

(j-k) 和 hk小于hj,面积 S2’= hk X(j-k),这两种情况下S1’和S2’都有大于S的可能性,即可能找到更大面积的水箱

如果选择–j,优先挪动高度较高的线段的下标,假设下标变为k,对应高度为hk,也有两种情况,hk大于=hi,面积S1’ =

hi*(k-i) ,很显然S1’小于S,如果hk小于等于hi,面积S2’ = hk X (k-i)小于S

,可以看到这种情况下找到的面积始终都小于我们当前面积S,这种方法还找个卵子最大面积?

综上所述,每次挪动都必须挪动高度较低的那个线段所在的下标

代码如下:

int maxArea(vector<int>& height) {
int i = 0, j = height.size()-1;
if (i > j)
return 0;
int rslt = 0;
int tmpMax = 0;
while (i != j)
{
//求出最大面积
if (height[i] < height[j])
{
tmpMax = height[i] * (j - i);
++i;
}
else
{
tmpMax = height[j] * (j - i);
--j;
}
//进行更新
if (tmpMax > rslt)
rslt = tmpMax;
}
return rslt;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  Container Most-Water