11. 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 and n is at least 2.

【解析】

题意:在二维坐标系中,(i, ai) 表示 从 (i, 0) 到 (i, ai) 的一条线段,任意两条这样的线段和 x 轴组成一个木桶,找出能够盛水最多的木桶,返回其容积。

两层 for 循环的暴力法会超时,所以尽早放弃这种懒惰的想法。

有没有 O(n) 的解法?

答案是有,用两个指针从两端开始向中间靠拢,如果左端线段短于右端,那么左端右移,反之右端左移,知道左右两端移到中间重合,记录这个过程中每一次组成木桶的容积,返回其中最大的。(想想这样为何合理?)

合理性解释:当左端线段L小于右端线段R时,我们把L右移,这时舍弃的是L与右端其他线段(R-1, R-2, ...)组成的木桶,这些木桶是没必要判断的,因为这些木桶的容积肯定都没有L和R组成的木桶容积大。

 1 class Solution(object):
 2     '''
 3     题意:任取两个a[i]、a[j] 使得min(a[i], a[j]) * abs(i - j)最大化
 4     用两个指针从两侧向中间扫描,每次移动数值较小的指针,用反证法可以证明
 5     总是可以得到最优答案
 6     '''
 7     def maxArea(self, height):
 8         left, right = 0, len(height) - 1
 9         ans = 0
10         while left != right:
11             if height[left] < height[right]:
12                 area = height[left] * (right - left)
13                 left += 1
14             else:
15                 area = height[right] * (right - left)
16                 right -= 1
17             ans = max(ans, area) 
18         return ans

 

posted @ 2017-05-22 21:15  hafgyyb  阅读(93)  评论(0)    收藏  举报