LeetCode #11 Container With Most Water - 刷題之旅
1 題目描述
給定一個非負整數的數組height
,每個元素代表一個垂直線,並且每個線的寬度都是1。找出兩條線,使得他們和x軸組成的容器可以容納最多的水。
(注意不可以傾斜容器)
2 解法
2.1 暴力解法
這題的暴力破解是O(N)基本上就是遍歷所有的組合,找出最大的容器。
1 | class Solution: |
2.2 Speed O(N)
從知道這是two pointer的時候就要有個認知,那就是某種程度上他是有序的,這個案例有兩個變數,在計算面積 = 距離(指標距離) * 高度(min指標值)
,我們知道,距離
最大的狀況下是頭跟尾,但是window縮小的時候距離
只會越來越小,他是有序的。
然而這題比較困難的點是,我們要如何確保windows之外已經算過不可能有比目前最佳解還要好的前提下來縮window,因為距離
是有跡可循,window縮小的時候只會更小,因此找到最大面積的關鍵是高度(min指標值)
,他是一個不確定的因素,有可能window縮小時獲得更大的面積只是因為容器夠高,那我們要怎麼或得最大容器面積呢?
有三個重要概念
- 如果發現比
max_area
大的面積,就更新max_area
- 因為window縮小的時候,距離一定是縮短的,所以我們不避顧慮
距離(指標位置)
在windows之外有沒有可能有最佳解,因為我們最先計算的就是最大的距離left=0
和right=len(height)-1
。windows之外都是已經算過了,我們也把當前windows外的最佳解存在max_area
。 - 在縮window時真正會影響有沒有最佳解的是
高度(指標值)
,決定是否要移動pointer時,只要考慮高度
即可。- 如果
height[left] < height[right]
,那麼我們就移動left
,因為height[left]
是最小的,所以我們要找更大的height
。 - 如果
height[left] > height[right]
,那麼我們就移動right
,因為height[right]
是最小的,所以我們要找更大的height
。 - 如果
height[left] == height[right]
,那麼我們就移動left
或right
都可以,因為他們都是最小的,所以我們要找更大的height
。
- 如果
1 | # 初始狀態 |
完整程式碼可以寫成
1 | """ |
3 結語
這題我最大的困難仍是不習慣一個觀點:如果有多個要素(以這個例子是長度
跟高度
)在移動指標時我該怎麼考量確保 windows 之外已經算過不可能有比目前最佳解還要好的前提下來縮 window?
- 所以我們只要考量
高度
即可,因為高度
是不確定的,所以我們要找最大的高度
來縮window。 - 只有在確定windows之外確定不可能有沒算過的最佳解,我才會選擇縮windows來尋找可能的最佳解。
本部落格所有文章除特別聲明外,均採用 CC BY-NC-SA 4.0 許可協議。轉載請註明來自 Shannon's Blog 🐟 技術 | 生活 | 旅行! 如果你覺得我的文章有幫助,希望你可以到我的 github 給我一個 star ⭐️ Shannon Blog Repo
評論