leetcode 11. Container With Most Water

第一次认真写题解,有几个原因,这个题目比较像17年校赛那道没做出来的题,

二是因为O(n^2)的算法python实现超时了,java没超时,所以必须想一个更快的算法。

三是因为忘记把py项目里的venv加入到.gitignore,想把多个文件夹下的venv删除废了点功夫(不好好看文档的后果)

问题描述:给定一个容器,里面有多个间距为1,长度不同的挡板,给定一个整数数组, 代表挡板的高度。问如何装水试水最多?

方法一:O(n^2)的暴力写法,枚举两个端点,然后短的一边*间距 取最大值即可,java通过,py超时。

方法二:类似贪心算法。使用两个指针,指向数组首尾,同时向中间移动。问题在于,移动哪一边的指针?比较容易能猜出移动指向的值较小的那一边。

论证如下:
我们先假设 左端点的值小于有端点的值,我们无脑把左端点右移,比较移动后的右端点和左端点的值。

  1. 左<右

    容器高度取决于左边,与原容器相比,低变短,高也变短,容积小于原容器

  2. 左==右

    高度不变,底变短,容积小于元容器

  3. 左>右

    高度取决于右边,与原容器相比,底变短,高不变,容积小于原容器

综上所述,移动较长一边的端点得到的结果总比原来差,不符合贪心的准则。所以我们移动较短的一边即可得到最优解。

class Solution:
    def maxArea(self, height):
        maxV = 0
        i = 0
        j = len(height) - 1

        while i < j:
            t = (j - i) * min(height[i], height[j])
            maxV = max(maxV, t)
            if height[i] < height[j]:
                tt = height[i]
                i += 1
                while i < j and height[i] < tt:
                    i += 1
            else:
                tt = height[j]
                j-=1
                while i < j and height[j] < tt:
                    j -= 1

        return maxV

你可能感兴趣的:(leetcode 11. Container With Most Water)