Container With Most Water

这是一道应用题,题目讲的是,在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根竖线所组成的容器

Container With Most Water_第1张图片

第一个想法肯定是穷尽的,把两根的组合都试一遍,从暴力上解决问题。

但是!!!!
这样做算法题的意义就没有了,况且,leetcode是不会让你过的哈哈。

用穷尽算法的时候,我们就忽略了一些关键因素:
1.短板效应,容器能装的水由较短的那根竖线说了算
2.X轴的长度是有限的,贪心点的算法都知道从两边向中间收缩,这样就可以保证起码底是最长的。

如下图,一开始,我们用两边的两根作为容器的边缘
Container With Most Water_第2张图片

以下,我们注意到,两个边缘向中间收缩的时候有两个选择,左边缘向右动,或者右边缘向左动。但根据短板效应,现在是右边比较长,所以无论右边缘怎么动,都会导致一个结果——容器的高不可能比左边缘更高,并且容器的底还变短了。所以答案是,只能是左边缘向右动。

那么左边缘向右动的话,只需要验算长度比原来长的这一种情况的面积就OK了,也就是比原来短的边缘根本不用验算面积。
Container With Most Water_第3张图片

下一次操作再以此类推,直到最后即可!

附上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

Container With Most Water_第4张图片

你可能感兴趣的:(leetcode)