LeetCode#11 Container With Most Water

Problem Definition:

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.

Solution: 使用两个游标分别从height数组的起止位置开始往里靠。令i=0,j=len(height)-1。

每次只移动其中一个游标:把对应高度较小的游标往里移。形式化表示:

if height[ i ]<height[ j ]

  then i++

else

  j--

用一个实例来演示:

下图中的圆圈表示中间省略了很多杠杠。

1)i,j分别位于两端。height[i]<height[j],图中蓝色虚线跨过的区域就是以 i 为左边界所能得到的最大区域。(以 i 为左边界的区域,其高最大也就height[i],j再往左移,既不会增加高,又会减小底边长度)

    然而对于 j 所对应的杆子来说,它是被 i 所拖累的,它有潜能形成更大的区域。应该把 i 右移来寻找更大的以j为右边界的区域。当然 i 往右移后不一定能得到一个 i',j 之间的更大区域,但是有机会啊。(当 height[ i ]*(j-i)<(min(height[ i'],height[j])*(j-i')))

2)i右移一步以后。height[i]>height[j]。

3)j左移一步......

 

走到上图这个状态,可以发现节省了很多不必要的计算(相比于暴力破解):

1._比如没有计算 [0, 5]这个区域。因为已经计算过的[0, 6]覆盖了[0, 5];

2._比如不会再去计算[2, 6]。因为已经计算过的[1,6]覆盖了[2, 6]...

 

如此一直进行到 i>=j为止。

 1     # @param {integer[]} height
 2     # @return {integer}
 3     def maxArea(height):
 4         maxWater,i,j=0,0,len(height)-1
 5         while i<j:
 6             if height[i]<height[j]:
 7                 water=(j-i)*height[i]
 8                 i+=1
 9             else:
10                 water=(j-i)*height[j]
11                 j-=1
12             maxWater=max(maxWater,water)
13         return maxWater

 

posted @ 2015-07-28 21:17  曾可爱  阅读(121)  评论(0编辑  收藏  举报