leetcode解題得的原始碼,解題思路在程式碼的註釋裡。
- 我的leetcode主頁https://leetcode-cn.com/u/boywithacoin_cn/
- 我的個人部落格https://boywithacoin.cn/
- github_所有原始碼網址https://github.com/Freen247/leetcode
給定 n 個非負整數 a1,a2,...,an,每個數代表座標中的一個點 (i, ai) 。在座標內畫 n 條垂直線,垂直線 i 的兩個端點分別為 (i, ai) 和 (i, 0)。找出其中的兩條線,使得它們與 x 軸共同構成的容器可以容納最多的水。
題目原址:https://leetcode-cn.com/problems/container...
使用:vscode
Brute-force/暴力法
通過遞迴的思想來用暴力法遍歷所有資料
程式碼:
#
# @lc app=leetcode.cn id=11 lang=python3
#
# [11] 盛最多水的容器
#
# @lc code=start
from typing import List
class Solution:
def __init__(self):
self.maxContent = 0
def force(self, height: List[int]) -> int:
# print(len(height))
# get the last one & del it
last = height.pop()
for key,value in enumerate(height):
# Short board effect, get the minimm value between the last one & current value
tmp = min(last,value)*(len(height)-key)
self.maxContent = max(tmp,self.maxContent)
# print(self.maxContent)
if len(height) == 1:
return self.maxContent
else:
#Iterativly call self.force() with new params height
return(self.force(height))
def maxArea(self, height: List[int]) -> int:
return {
0 :lambda height :self.force(height),
}[0](height)
# @lc code=end
if __name__ == "__main__":
solve = Solution()
print(solve.maxArea([1,8,6,2,5,4,8,3,7]))
提交效果:
- 42 / 50 個通過測試用例
- 狀態:超出時間限制
複雜度分析:
- time complexity :$O(n^{2})$ ,計算所有$\frac{n(n-1)}{2}$ 種高度組合的面積
- space complexity :$O(1)$,使用恆定的
self.maxContent
空間
Double-pointer/雙指標法
傳統方法,兩個指標,分別指向the first one
和the last one
,另外使用self.maxContent
來儲存最大的面積。
最初我們考慮由最外圍兩條線段構成的區域。現在,為了使面積最大化,我們需要考慮更長的兩條線段之間的區域。如果我們試圖將指向較長線段的指標向內側移動,矩形區域的面積將受限於較短的線段而不會獲得任何增加。但是,在同樣的條件下,移動指向較短線段的指標儘管造成了矩形寬度的減小,但卻可能會有助於面積的增大。因為移動較短線段的指標會得到一條相對較長的線段,這可以克服由寬度減小而引起的面積減小。
兩個指標相互靠近時,矩形的底是變小的,所以只有高變大才有可能面積變大,所以讓短的向長的那個靠近。
程式碼:
#
# @lc app=leetcode.cn id=11 lang=python3
#
# [11] 盛最多水的容器
#
# @lc code=start
from typing import List
class Solution:
def __init__(self):
self.maxContent = 0
def burte_force(self, height: List[int]) -> int:
# print(len(height))
# get the last one & del it
last = height.pop()
for key,value in enumerate(height):
# Short board effect, get the minimm value between the last one & current value
tmp = min(last,value)*(len(height)-key)
self.maxContent = max(tmp,self.maxContent)
# print(self.maxContent)
if len(height) == 1:
return self.maxContent
else:
#Iterativly call self.burte_force() with new params height
return(self.burte_force(height))
def double_pointer(self, height: List[int]) -> int:
i, j= 0, len(height) - 1
while i < j:
# the pointers approach eacher other, their distance becomes smaller, so the only when the short one approach the long one the area can be larger.
if height[i] < height[j]:
self.maxContent = max(self.maxContent, height[i] * (j - i))
# the left pointer move right
i += 1
else:
self.maxContent = max(self.maxContent, height[j] * (j - i))
# the right pointer move left
j -= 1
return self.maxContent
def maxArea(self, height: List[int]) -> int:
return {
0 :lambda height :self.burte_force(height),
1 :lambda height :self.double_pointer(height),
}[1](height)
# @lc code=end
if __name__ == "__main__":
solve = Solution()
print(solve.maxArea([1,8,6,2,5,4,8,3,7]))
提交效果:
Accepted
- 50/50 cases passed (148 ms)
- Your runtime beats 66.95 % of python3 submissions
- Your memory usage beats 50.48 % of python3 submissions (14.6 MB)
複雜度分析:
- time complexity :$O(n)$ ,雙指標遍歷一次底邊寬度$N$。
- space complexity :$O(1)$,使用恆定的
self.maxContent
空間
本作品採用《CC 協議》,轉載必須註明作者和本文連結
文章!!首發於我的部落格Stray_Camel(^U^)ノ~YO。