LeetCode 11. Container With Most Water

Zetrue_Li發表於2018-04-25

一、問題描述:

    Given n non-negativeintegers a1a2, ..., an, where each represents a point atcoordinate (iai). n verticallines are drawn such that the two endpoints of line i is at (iai) and (i, 0). Find two lines, which togetherwith x-axis forms a container, such that the container contains the most water.

    Note: You maynot slant the container and n is at least 2.

 

二、問題分析:

根據問題描述,大致分析需求為:在a1a2, ..., an中找出兩個元素,不妨設為aiaj通過這兩個元素構獲得四個點(i, ai)、(i, 0)、(j, aj)(j, 0)。在座標系上分別連線(i, 0)和(j, 0)、(i, 0)和(i, ai)、 (j, 0)(j, aj) 構造出以一個開口向上的二維容器,大致影像如下:


容器的容量由兩個因素決定:

1.      ij的距離;

2.      aiaj的最小值;

容量大小公式為:|i-j| * min{ai, aj}

那麼,這樣就可以把問題簡化為:給定一個包含n個整數(a1a2, ..., an)的列表。要求找出兩個元素aiaj,滿足|i-j| * min{ai, aj} 為最大值。


三、演算法設計:

1.      初始化最大容量max = 0,分別定義a = 0 b = lenl

2.      a < b 時,迴圈執行以下操作:

從給定的列表l兩頭開始往列表中部遍歷,每次記錄temp = min{l[a],l[b]} * (b – a),比較tempmax的大小。如果temp > max,則max = temp

l[a] > l[b],則b = b-1

反之,則a = a + 1

3.      返回的max即為最大容量

原理:

因為從列表的兩頭往中間遍歷即能保證每次兩個元素的下標之差是最大的,且不會重複計算。因為容量由兩個元素資料的最小值決定,所以在每次記錄完只需要將較小的一個元素進行替換,替換出現兩種情況:更新元素後容器的容量比未更新的小,但是這對記錄的最大容量不產生影響;更新元素後的容器容量比未更新的大,此時就會更新記錄的最大容量。這樣設計的優點是可以避免計算包含有較小元素的容量計算,這是因為針對一個特定的元素,由於較大或較小兩個元素是往中間靠攏的距離,所以更新較大或較小的元素與另一個特定的元素組合的距離是一樣的,因此包含較小元素的容器容量一定比包含有較大元素的容器容量小。


四、程式實現:

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

相關文章