1. 程式人生 > >每天一道程式設計題 (補) LeetCode-Container With Most Water

每天一道程式設計題 (補) LeetCode-Container With Most Water

LeetCode上的題目太多了,每道都寫bolg實在是沒必要。接下來,小天會主要講解有趣的和重要的題目,這裡的重要是指題目有很大可能出現在面試中。

題目簡介:

這裡對題目作進一步形式化定義,給定一組非負整型數a_{1},a_{2},\cdots,a_{n},題目希望找到兩個數字a_{i},a_{j} \ i<j,使得目標函式(j-i)\times{min(a_i,a_j)}最小。

舉例說明:輸入一組非負整型數 [1,8,6,2,5,4,8,3,7]

由上圖可知,每個數字表示柱子的高度,題目希望找到兩個柱子可以裝下儘可能多的水。

解法一:

按照慣例,解法一般是暴力解法,可惜python的迴圈效率實在是低了點,整型數一多,兩重迴圈就直接超時了。但思路還是可以瞭解一下,遍歷所有的a_{i},a_{j} \ i<j整型數對,總共需要遍歷作\binom{n}{2}次。

解法二:兩指標法

在採用解法二之前,小天嘗試過很多方法將複雜度降至O(n),但大多是不可行的。其實,這道題雖然可以被形式是一道最優化題,但實際上還是一道搜尋題。解法二中初始化兩個指標分別指向陣列的兩端,然後判斷兩指標多所指向的整型數,捨棄較小數,將其指標往裡移動。因為每次只移動一個指標,故而時間複雜度降低至O(n)

官網給出非常詳細的解釋,因為初始化條件下,所佔長度是最長的。左右兩邊無論哪一邊向內移動,佔用長度上都是相同的,那隻需要決策出那種移動更有利即可。另一方面,可容納的水量受到較短高度的限制,每次捨去較短長度可以增加限制。

class Solution:
    def maxArea(self, height):
        """
        :type height: List[int]
        :rtype: int
        """
        n, m = 0, len(height) - 1
        max_area = 0
        while n < m:
            max_area = max(max_area, min(height[n], height[m]) * (m - n))
            if height[n] > height[m]: m -= 1
            else: n += 1
        return max_area 

總結:

LeetCode上的題目大多從真實的專案中抽象出來,非常適合練手。