leetcode11. 盛最多水的容器

97 阅读2分钟

11. 盛最多水的容器

给定 n 个非负整数 a1,a2,...,an,每个数代表坐标中的一个点 (i, ai) 。在坐标内画 n 条垂直线,垂直线 i 的两个端点分别为 (i, ai) 和 (i, 0)。找出其中的两条线,使得它们与 x 轴共同构成的容器可以容纳最多的水。你不能倾斜容器,且 n 的值至少为 2。

img

图中垂直线代表输入数组 [1,8,6,2,5,4,8,3,7]。在此情况下,容器能够容纳水(表示为蓝色部分)的最大值为 49。

class Solution(object):
    def maxArea(self, height):
        # :type height: List[int]
        # :rtype: int
        i, j, res = 0, len(height) - 1, 0
        while i < j:
            if height[i] < height[j]:
                res = max(res, height[i] * (j - i))
                i += 1
            else:
                res = max(res, height[j] * (j - i))
                j -= 1
        return res
"""
设置双指针 i,j 分别位于容器壁两端,根据规则移动指针(每次选定围成水槽两板高度 h[i],h[j] 中的短板,向中间收窄 1 格),并且更新面积最大值 res,直到 i == j 时返回 res。
证明:
设每一状态下水槽面积为 S(i, j),(0<=i<j<n),水槽的实际高度由短板决定,所以S(i,j)=min(h[i],h[j])×(j−i)。
在每一个状态下,无论长板或短板收窄1格,都会导致水槽底边宽度−1:
若向内移动短板,水槽的短板min(h[i],h[j]) 可能变大,因此水槽面积 S(i, j)S(i,j) 可能增大。
若向内移动长板,水槽的短板min(h[i],h[j]) 不变或变小,下个水槽的面积一定小于当前水槽面积。
因此,向内收窄短板可以获取面积最大值。
通俗的讲,我们每次向内移动短板,所有的消去状态都不会导致丢失面积最大值 。
"""