繼第二天的「160. Intersection of Two Linked Lists」,今天來解 121 這題!還沒看過第二天或再之前天數的朋友,歡迎也去看看~
我們開始吧!
這篇會加入如何規劃、以及如何模擬解法的概略說明,別錯過囉!
給予一個 prices 陣列,而 prices[i]
的 i
為第 i 天的股價。
需要得透過選擇一天買入,並在該天的未來日賣出,需要得出最大獲利並回傳。
如果無法獲利,則回傳 0 。
prices = [7, 1, 5, 3, 6, 4]
天數為 array 之 index 。以這個例子在第一天 (股價: 1) 買,在第四天 (股價: 6) 賣出能得到最大獲利
6 - 1 = 0
prices = [5, 4, 3]
同樣,天數為 array 之 index 。以這個例子在最便宜的第二天 (股價: 3) 買,但是在那之後已經無法交易了,所以沒有獲利,因此回傳 0 。
提早結束條件
接著思考核心的 routine
class Solution {
func maxProfit(_ prices: [Int]) -> Int {
if prices.isEmpty { return 0 }
var maxProfit = 0
for buy in 0..<(prices.count-1) {
for sell in buy..<prices.count {
maxProfit = max(maxProfit, prices[sell] - prices[buy])
}
}
return maxProfit
}
}
Time Limit Exceeded
Big O | 說明 | |
---|---|---|
時間複雜度 | O(n^2) | 走訪兩層迴圈 |
空間複雜度 | O(1) | 走訪之間沒有使用到多餘的記憶體 |
在解法 1 中只有暫存最大獲利,但是每一次都在重新尋找最低值。如果能夠以貪婪的方式,只要找到最低值就暫存下來,就可以避免不需要的計算。
提早結束條件
準備必要的變數
接著思考核心的 routine
當規劃完核心 routine 之後,可以試著用紙筆模擬走訪的結果,同時並思考有沒有邏輯錯誤和 edge cases 。
在面試的情境下,這個階段可以跟面試官討論自己的思考方式,除了可以在動手前確保邏輯沒問題,也可以從面試官的回饋得知可能缺失的地方。
確認沒有問題後,再開始動手開始寫程式碼也還來得及。
class Solution {
func maxProfit(_ prices: [Int]) -> Int {
if prices.isEmpty { return 0 }
var minPrice = Int.max
var maxProfit = 0
for price in prices {
minPrice = min(minPrice, price)
maxProfit = max(maxProfit, price - minPrice)
}
return maxProfit
}
}
Big O | 說明 | |
---|---|---|
時間複雜度 | O(n) | 只有一層回圈,1 pass |
空間複雜度 | O(1) | 只有使用到常數個多餘的空間 O(2) ,簡化後為 O(1) |
解法 | 時間複雜度 | Runtime | 空間複雜度 | Memory |
---|---|---|---|---|
1. 暴力解 | O(n^2) | TLE | O(1) | TLE |
2. Greedy | O(n) | 778 ms | O(1) | 18.1 MB |
從 Greedy 的角度思考的時候,會開始想如何簡化掉不必要的運算,就能夠大大降低時間複雜度,減少運行時間。但是該怎麼降,還是需要多做題目體會換經驗。
如果有任何回饋或是文中寫不清楚的地方,歡迎在下面留言!
今天就到這裡,明天見!