leetcode 11. 盛最多水的容器 - 兩種解法 - python

題目
給定 n 個非負整數 a1,a2,...,an,每一個數表明座標中的一個點 (i, ai) 。在座標內畫 n 條垂直線,垂直線 i 的兩個端點分別爲 (i, ai) 和 (i, 0)。找出其中的兩條線,使得它們與 x 軸共同構成的容器能夠容納最多的水。python

說明:你不能傾斜容器,且 n 的值至少爲 2。數組

image

圖中垂直線表明輸入數組 [1,8,6,2,5,4,8,3,7]。在此狀況下,容器可以容納水(表示爲藍色部分)的最大值爲 49。app

解答

方法一:排序加遍歷,時間複雜度O(nlogn)

從大到小排序
維護三個變量:
當前的最低高度,當前最左,當前最右
最大面積就是 當前高度 × (當前最右 - 當前最左)spa

class Solution:
    def maxArea(self, height: List[int]) -> int:
        x = []
        for i, n in enumerate(height):
            x.append((i, n))
        x.sort(key=lambda x:x[1], reverse=True)
        h = min(x[0][1], x[1][1])
        l = min(x[0][0], x[1][0])
        r = max(x[0][0], x[1][0])
        ans = h * (r - l)
        for i in range(2, len(x)):
            l = min(x[i][0], l)
            r = max(x[i][0], r)
            h = min(h, x[i][1])
            ans = max(ans, h * (r - l))
        return ans

方法二:雙指針, 時間複雜度O(n)

這個問題的最優解有一個特色:
若是 i 和 j 位置是最大容量,則要麼 「i 是 0 到 i 中高度最高的」 要麼 「j 是從 j 到最後中 高度最高的」。
由於若是兩個都不知足,選擇這兩個最高的獲得的容量必定比 i,j 容量要高。指針

因此這樣能夠採起先令 i = 0, 令 j = len(height)code

而後循環計算當前容量,每次循環若是 i 的高度大於 j 則 j-= 1
若是 i 的高度小於 j 則 i -= 1blog

記錄下過程當中的最大容量,就是答案。排序

class Solution:
    def maxArea(self, height: List[int]) -> int:
        i = 0
        j = len(height)-1
        ans = 0
        while i < j:
            ans = max(ans, (j - i) * min(height[i], height[j]))
            if height[i] < height[j]:
                i += 1
            else:
                j -= 1
        return ans
相關文章
相關標籤/搜索