1. 程式人生 > >盛最多水的容器

盛最多水的容器

好的 urn ret tin tmp class 提高 同構 elf

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

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

1. 題目需要理解的一點,垂直線的寬度忽略不計,也就是說width = n -1

2. 一開始並沒有什麽好的方法,後來才意識到其實這題的關鍵在於隱藏信息

class Solution(object):
    def maxArea(self, height):
        """
        :type height: List[int]
        :rtype: int
        """
        max_area = 0
        length = len(height)
        x_tmp = -1
        y_tmp = -1
        for i in range(length-1):
            x = height[i]
            if x>x_tmp:
                y_list = [i for i in range(i+1,length)][::-1]
                for j in y_list:
                    y = height[j]
                    if y>y_tmp:
                        area = min(height[i],height[j])*(j-i)
                        if area>max_area:
                            max_area = area
                    else:
                        continue
            else:
                continue
        return max_area

上述代碼先從兩端開始,因為寬度是逐漸減小的,因此必須使得高度是增加的,因此僅在後者高度大於前者,才計算area。

然而時間復雜度還是O(n*n),是不符合題目要求的。

正解:

其實是我們忽略了一個隱藏條件,因為根據短板效應,實際上我們需要增大的是短的那塊板,因此還可以提高速度。

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

盛最多水的容器