今天偶然遇到一個(gè)買賣股票最佳時(shí)機(jī)(best-time-to-buy-and-sell-stock)的問題。這個(gè)問題本身是個(gè)簡(jiǎn)單問題,暴力解法(尋找每種時(shí)間組合)和迭代法(尋找差值最大的波峰波谷)都可以解決該問題。如果用動(dòng)態(tài)規(guī)劃的方法需要稍微拐個(gè)彎。寫個(gè)文章順便復(fù)習(xí)一下Dynamic Programing。
問題描述:
Say you have an array for which the ith element is the price of a given stock on day i.
If you were only permitted to complete at most one transaction (i.e., buy one and sell one share of the stock), design an algorithm to find the maximum profit.
Note that you cannot sell a stock before you buy one.
Example 1:
Input: [7,1,5,3,6,4]
Output: 5
Explanation: Buy on day 2 (price = 1) and sell on day 5 (price = 6), profit = 6-1 = 5.
Not 7-1 = 6, as selling price needs to be larger than buying price.
Example 2:
Input: [7,6,4,3,1]
Output: 0
Explanation: In this case, no transaction is done, i.e. max profit = 0.
上面意思就是:有個(gè)數(shù)組記錄著每天的股票價(jià)格,你選擇一天買選擇一天賣(記為一次交易,當(dāng)然是先買再賣)使得獲利最多。利潤(rùn)為負(fù)就返回0.
遞歸方法解:
arr = [7, 1, 5, 3, 6, 4]
arr1 = [7, 6, 5, 4, 3, 2, 1]
def rec_opt(arr, i):
if i == 1: #出口
p = arr[i] - arr[0]
return 0 if p<0 else p
else: #迭代式
A = arr[i] - min(arr[:i])
B = rec_opt(arr, i-1)
p = max(A, B)
return 0 if p<0 else p
print(rec_opt(arr, len(arr)-1))#5
print(rec_opt(arr1, len(arr1)-1))#0
上面代碼在Leetcode上因?yàn)閮?nèi)存的限制是不通過的。測(cè)試用例數(shù)組增大,遞歸的調(diào)用深度增大。遞歸方法解DP問題的關(guān)鍵是找到迭代式和迭代出口。而且遞歸方法通常會(huì)出現(xiàn)重疊子問題算法時(shí)間復(fù)雜度為O(2**n),這時(shí)可以開辟一個(gè)數(shù)組記錄子問題的解,避免重復(fù)計(jì)算,以空間換時(shí)間。但是在該問題中沒有出現(xiàn)重疊子問題。就不轉(zhuǎn)成迭代的方法了。