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.
Example:
Input: [1,8,6,2,5,4,8,3,7] Output: 49
中文题意大概是将列表中随便两个元素的 索引差当做长,两个元素值取小的那个当做高,面积 = 长 * 高。取一个列表可能出现的面积最大值。
最简单的方法是遍历两次列表(负责度 O(n^2)),求出所有的面积然后取最大的,但是这里有算法要求,复杂度太高会超时,所以只能用复杂度更低的算法。
这里有个规律:如果从两端开始取值,则值小的那个所能产生的面积最大值已经确定。因为 面积的高取两个元素较小的那个,最大的高已经确定只需要选择最大的长,已经是索引差最大的另一端。
举例:a = [2,8,6,1,5,4,8,3,7] a[0]与a[len(a)] 比较大小,a[0]更小,那么能让a[0]能产生的最大值的元素只有a[len(a)], 因为其他元素比a[0]大没有意义。高取的是小元素,比a[0]小的元素更没有意义,这里需要的最大值。所以只要确定一端的元素小,能取到最大面积的元素肯定在另一端。值小的元素取完后就可以往里面继续取了,因为它的存在毫无意义。
代码如下:
class Solution(object): def maxArea(self, height): maxa = 0 front = 0 #定义两个变量当做索引 behind = len(height) - 1 #从两端往中间取值,数值小的索引可以直接取到最大值,取完直接淘汰该索引 while True: if front == behind: #取到索引相同位为止 break elif height[front] >= height[behind]: #最前端的数大于最后端则最后一个值的最大值已经确定,可以取完淘汰了 area = height[behind]*(behind - front) behind -= 1 if area > maxa: maxa = area else: #同上 area = height[front]*(behind - front) front += 1 if area > maxa: maxa = area return maxa
这个算法时间复杂度是 O(n).
解题思路参考了博客园的其他文章。
Ry_Chen
原文地址:https://www.cnblogs.com/slarker/p/Ry_Chen.html