股票最大收益問題
給定一個陣列,它的第
i個元素是一支給定股票第i天的價格。設計一個演算法來計算你所能獲取的最大利潤。你可以儘可能地完成更多的交易(多次買賣一支股票)。
注意: 你不能同時參與多筆交易(你必須在再次購買前出售掉之前的股票)。測試用例:
輸入: [7,1,5,3,6,4]輸出: 7解釋: 在第 2 天(股票價格 = 1)的時候買入,在第 3 天(股票價格 = 5)的時候賣出, 這筆交易所能獲得利潤 = 5-1 = 4 。
隨後,在第 4 天(股票價格 = 3)的時候買入,在第 5 天(股票價格 = 6)的時候賣出, 這筆交易所能獲得利潤 = 6-3 = 3 。複製程式碼
輸入: [7,6,4,3,1]輸出: 0解釋: 在這種情況下, 沒有交易完成, 所以最大利潤為 0。複製程式碼
解決方案1 :時間複雜度 o(n^2)解題思路:
1 思考好兩個時機即可,什麼時間會買入,什麼時間會賣出
2 買入:當發現後一個價格比當前價格高,肯定會買入
3 賣出:當發現買入之後的價格中,存在價格下滑時,在下滑前或者不再升高前賣出
備註:存在多次交易,所以必然是一直迴圈 ; 不能同時交易,所以賣出和買入的操作不能同時進行,決定買入的行為中不會有賣出,賣出的行為中也絕對沒有買入,導致的程式碼邏輯就是指標會加一。
/** * @param {number[]
} prices * @return {number
} */var maxProfit = function(prices) {
if(!prices || !prices.length) return 0 let maxProfit = 0 for(let i=0,len=prices.length;
i<
len;
i++){
// 發現之後的價格有提升的時候才會考慮買入 if(prices[i]<
prices[i+1]){
// 迴圈決定什麼時候會賣出 for(let t=i+1;
t<
len;
t++){
// 當股票價格開始下降或者達到最後一個的時候 是決定賣出了 if(prices[t]>
prices[t+1]||t==len-1){
maxProfit += prices[t] - prices[i] i= t+1
}
}
}
} return maxProfit
};
複製程式碼
解決方案二 :動態規劃
解決思路:不管是什麼時候買入還是賣出,其實任何一次的買入和賣出的中間過程都可以看成中間連續買入賣出的疊加。比如m(4)-m(2) = m(4)-m(3)+m(3)-m(2),而最大收益其實就是隻計算那些我們通過對比相鄰天數得出的正數然後累加上去就是最大收入。
/** * @param {number[]
} prices * @return {number
} */var maxProfit = function(prices) {
if(!prices || !prices.length) return 0 let maxProfit = 0 for(let i=0,len=prices.length;
i<
len;
i++){
let ben = prices[i+1] - prices[i] if(ben>
0) maxProfit+= ben
} return maxProfit
};
複製程式碼
對比分析:當然,從結果來看方案二更高效,也更容易理解,方案一更符合大家的常規思維。但是方案二有一個短板就是還需要額外的程式碼去判斷什麼時候是買入和賣出的真正節點,雖然這道題沒有這個要求返回方案,但我們要考慮到這一點。