这是一道应用题,题目讲的是,在x轴上,每一个整数点都有一条竖线,竖线的长度由一个数组height描述。那么选择两条竖线,他们和x轴共同形成一个容器(类似一个烧杯)来装水,找到能够装最多水的两条竖线。
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.
举个栗子,下面就是选择了第1根和第2根竖线所组成的容器
第一个想法肯定是穷尽的,把两根的组合都试一遍,从暴力上解决问题。
但是!!!!
这样做算法题的意义就没有了,况且,leetcode是不会让你过的哈哈。
用穷尽算法的时候,我们就忽略了一些关键因素:
1.短板效应,容器能装的水由较短的那根竖线说了算
2.X轴的长度是有限的,贪心点的算法都知道从两边向中间收缩,这样就可以保证起码底是最长的。
如下图,一开始,我们用两边的两根作为容器的边缘
以下,我们注意到,两个边缘向中间收缩的时候有两个选择,左边缘向右动,或者右边缘向左动。但根据短板效应,现在是右边比较长,所以无论右边缘怎么动,都会导致一个结果——容器的高不可能比左边缘更高,并且容器的底还变短了。所以答案是,只能是左边缘向右动。
那么左边缘向右动的话,只需要验算长度比原来长的这一种情况的面积就OK了,也就是比原来短的边缘根本不用验算面积。
下一次操作再以此类推,直到最后即可!
附上python代码
class Solution(object):
def maxArea(self, height):
"""
:type height: List[int]
:rtype: int
"""
i = 0
j = len(height) - 1
biggest = j * min(height[i], height[j])
cur_left = height[0]
cur_right = height[j]
while i < j:
if height[i] < height[j]:
i += 1
if height[i] > cur_left:
cur_left = height[i]
area = (j - i) * min(height[i], height[j])
if area > biggest:
biggest = area
else:
j -= 1
if height[j] > cur_right:
cur_right = height[j]
area = (j - i) * min(height[i], height[j])
if area > biggest:
biggest = area
return biggest