Best Time to Buy and Sell Stock III -- LeetCode
原題連結:
http://oj.leetcode.com/problems/best-time-to-buy-and-sell-stock-iii/
這道題是 Best Time to Buy and Sell Stock 的擴充套件,現在我們最多可以進行兩次交易。我們仍然使用動態規劃來完成,事實上可以解決非常通用的情況,也就是最多進行k次交易的情況。
這裡我們先解釋最多可以進行k次交易的演算法,然後最多進行兩次我們只需要把k取成2即可。我們還是使用“區域性最優和全域性最優解法”。我們維護兩種量,一個是當前到達第i天可以最多進行j次交易,最好的利潤是多少(global[i][j]),另一個是當前到達第i天,最多可進行j次交易,並且最後一次交易在當天賣出的最好的利潤是多少(local[i][j])。下面我們來看遞推式,全域性的比較簡單,
上面的演算法中對於天數需要一次掃描,而每次要對交易次數進行遞推式求解,所以時間複雜度是O(n*k),如果是最多進行兩次交易,那麼複雜度還是O(n)。空間上只需要維護當天資料皆可以,所以是O(k),當k=2,則是O(1)。程式碼如下:
這道題是 Best Time to Buy and Sell Stock 的擴充套件,現在我們最多可以進行兩次交易。我們仍然使用動態規劃來完成,事實上可以解決非常通用的情況,也就是最多進行k次交易的情況。
這裡我們先解釋最多可以進行k次交易的演算法,然後最多進行兩次我們只需要把k取成2即可。我們還是使用“區域性最優和全域性最優解法”。我們維護兩種量,一個是當前到達第i天可以最多進行j次交易,最好的利潤是多少(global[i][j]),另一個是當前到達第i天,最多可進行j次交易,並且最後一次交易在當天賣出的最好的利潤是多少(local[i][j])。下面我們來看遞推式,全域性的比較簡單,
global[i][j]=max(local[i][j],global[i-1][j]),
也就是去當前區域性最好的,和過往全域性最好的中大的那個(因為最後一次交易如果包含當前天一定在區域性最好的裡面,否則一定在過往全域性最優的裡面)。對於區域性變數的維護,遞推式是
local[i][j]=max(global[i-1][j-1]+max(diff,0),local[i-1][j]+diff),
也就是看兩個量,第一個是全域性到i-1天進行j-1次交易,然後加上今天的交易,如果今天是賺錢的話(也就是前面只要j-1次交易,最後一次交易取當前天),第二個量則是取local第i-1天j次交易,然後加上今天的差值(這裡因為local[i-1][j]比如包含第i-1天賣出的交易,所以現在變成第i天賣出,並不會增加交易次數,而且這裡無論diff是不是大於0都一定要加上,因為否則就不滿足local[i][j]必須在最後一天賣出的條件了)。
上面的演算法中對於天數需要一次掃描,而每次要對交易次數進行遞推式求解,所以時間複雜度是O(n*k),如果是最多進行兩次交易,那麼複雜度還是O(n)。空間上只需要維護當天資料皆可以,所以是O(k),當k=2,則是O(1)。程式碼如下:
public int maxProfit(int[] prices) {
if(prices==null || prices.length==0)
return 0;
int[] local = new int[3];
int[] global = new int[3];
for(int i=0;i<prices.length-1;i++)
{
int diff = prices[i+1]-prices[i];
for(int j=2;j>=1;j--)
{
local[j] = Math.max(global[j-1]+(diff>0?diff:0), local[j]+diff);
global[j] = Math.max(local[j],global[j]);
}
}
return global[2];
}
可以看到,這裡的模型是比較複雜的,主要是在遞推式中,local和global是交替求解的。不過理清思路之後,程式碼是非常簡練的,不禁感嘆演算法真是牛逼哈,這麼個複雜生活問題幾行程式碼就解決了。
相關文章
- leetcode best-time-to-buy-and-sell-stock-iii(Java)LeetCodeJava
- [leetcode]Best Time to Buy and Sell StockLeetCode
- [LeetCode] 121. Best Time to Buy and Sell StockLeetCode
- leetcode_best-time-to-buy-and-sell-stock-iiLeetCode
- LeetCode 309. Best Time to Buy and Sell Stock with CooldownLeetCode
- [LeetCode] 122. Best Time to Buy and Sell Stock IILeetCode
- Best Time to Buy and Sell Stock系列
- 121|Best Time to Buy and Sell Stock
- 121. Best Time to Buy and Sell Stock
- Best Time to Buy and Sell Stock系列分析
- 貪心法-Best Time to Buy and Sell Stock
- 【Lintcode】393. Best Time to Buy and Sell Stock IV
- 42-best-time-to-buy-and-sell-stock-iii 力扣 123. 買賣股票的最佳時機 III力扣
- 【leetcode】40-best-time-to-buy-and-sell-stock 力扣 121. 買賣股票的最佳時機LeetCode力扣
- 【LeetCode】309. Best Time to Buy and Sell Stock with Cooldown 最佳買賣股票時機含冷凍期(Medium)(JAVA)LeetCodeJava
- 44-best-time-to-buy-and-sell-stock-with-cooldown 力扣 309. 買賣股票的最佳時機包含冷凍期力扣
- [LeetCode] 2073. Time Needed to Buy TicketsLeetCode
- Time Series Analysis (Best MSE Predictor & Best Linear Predictor)
- The best LeetCode NodesLeetCode
- [LintCode/LeetCode] Contains Duplicate IIILeetCodeAI
- [LeetCode] 248. Strobogrammatic Number IIILeetCode
- [LeetCode] 3163. String Compression IIILeetCode
- [LeetCode] Employee Free TimeLeetCode
- Leetcode——437. 路徑總和 IIILeetCode
- [LeetCode] 681. Next Closest TimeLeetCode
- Leetcode 之 PHP 解析 (260. Single Number III)LeetCodePHP
- Leetcode 1375. Bulb Switcher III (python+cpp)LeetCodePython
- 【PAT_1062】To Buy or Not to Buy
- leetcode 123 買賣股票的最佳時機 IIILeetCode
- LeetCode 只出現一次的數字IIILeetCode
- leetcode —— 1004. 最大連續1的個數 IIILeetCode
- [Leetcode學習-c++&java]Next Greater Element I ~ IIILeetCodeC++Java
- Leetcode 960:刪列造序 III(超詳細的解法!!!)LeetCode
- TTEC遭勒索軟體攻擊後影響客戶業務 包括Verizon、Best Buy、美國銀行等
- leetcode力扣 1004. 最大連續1的個數 IIILeetCode力扣
- SAP Stock Inconsistency
- LeetCode每日一題:反轉字串中的單詞 III(No.557)LeetCode每日一題字串
- Hackable: III
- Best Team With No Conflicts