問題描述
You are given an integer array height
of length n
. There are n
vertical lines drawn such that the two endpoints of the ith
line are (i, 0)
and (i, height[i])
.
Find two lines that together with the x-axis form a container, such that the container contains the most water.
Return the maximum amount of water a container can store.
Notice that you may not slant the container.
限制條件
n == height.length
2 <= n <= 105
0 <= height[i] <= 104
範例
- Example 1:
Input:height = [1, 8, 6, 2, 5, 4, 8, 3, 7]
Output:49
Explanation: The above vertical lines are represented by array[1, 8, 6, 2, 5, 4, 8, 3, 7]
. In this case, the max area of water (blue section) the container can contain is49
. - Example: 2
Input:height = [1, 1]
Output:1
解法一:暴力解
步驟詳解
- 使用一個巢狀迴圈來遍歷所有的可能組合,並在遍歷過程中,持續更新最大容量
max_water
的數值。 - 遍歷結束後回傳
max_water
。
程式碼
def container_with_most_water(height: List[int]) -> int:
max_water = 0
for i, left_bound in enumerate(height):
for j, right_bound in enumerate(height):
water = min(left_bound, right_bound) * (j - i)
max_water = max(max_water, water)
return max_water
Python複雜度分析
- 時間複雜度:
O(N2)
,其中N
為height
的陣列長度。 - 空間複雜度:
O(1)
解法二:雙指針
解題思路
透過觀察,我們可以發現真正影響一個區域的裝水量多寡的主要條件是兩側邊界中較低的那一側:
由於我們的目標是最大化儲存水量,因此我們可以在遍歷的過程中,持續透過只移動兩側中較低的那側邊界來提升搜索效率。
步驟詳解
- 初始化變數
max_water
作為目前最大儲存水量。並建立兩個指針i
與j
,分別從陣列的最左側及最右側開始向內移動。 - 當左指針
i
始終在右指針j
的左側的時候,持續進行迭代檢查:- 首先計算目前範圍的儲存水量
min(height[i], height[j]) * (j - i)
。 - 若當前水量大於目前最大儲存水量
max_water
,將其更新。 - 接著移動較低那側的邊界。
- 首先計算目前範圍的儲存水量
- 迭代結束後,回傳最大儲存水量
max_water
。
程式碼
def container_with_most_water(height: List[int]) -> int:
max_water = 0
i, j = 0, len(height) - 1
while i < j:
water = min(height[i], height[j]) * (j - i)
max_water = max(max_water, water)
if height[i] <= height[j]:
i += 1
else:
j -= 1
return max_water
Python複雜度分析
- 時間複雜度:
O(N)
,其中N
為height
的陣列長度。 - 空間複雜度:
O(1)
參考資料
- LeetCode 原題出處:Container With Most Water – LeetCode