[leetcode]123.買賣股票的最佳時機3
阿新 • • 發佈:2018-12-31
每天 -- iii max 題解 set ice 遍歷數組 問題
[原題鏈接][https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock-iii/]
分析:動態規劃+二分法。以第i天
為分界線,計算第i天之前進行一次交易
的最大收益left[i]
,和第i天之後進行一次交易
的最大收益right[i]
,最後遍歷一遍找到max{left[i] + right[i]} (0≤i≤n-1)
,就是最大收益。第i天之前和第i天之後進行一次的最大收益求法如最簡單的股票買賣問題。
再求解前先看看最簡單的求一次交易
的最大收益解法
/*用一個數組表示股票每天的價格,數組的第i個數表示股票在第i天的價格。 如果只允許進行一次交易,也就是說只允許買一支股票並賣掉,求最大的收益。 題解:動態規劃法。從前向後遍歷數組,記錄當前出現過的最低價格,作為買入價格,並計算以當天價格出售的收益,作為可能的最大收益,整個遍歷過程中,出現過的最大收益就是所求。*/ int maxProfit(const int prices[],const int len){ if(len<2) return 0; int maxProfit = 0; int curMin = prices[0]; /*發現只進行了一次遍歷*/ for (int i = 1; i < len;i++){ curMin = min(curMin, prices[i]); maxProfit = max(maxProfit, prices[i] - curMin); /*每次遍歷後的maxProfix就是 從prices[0]開始到prices[i]的最大收益*/ } return maxProfit; }
利用上述最簡單情況的求一次交易的最大收益方法,順序遍歷一遍把每個階段的maxProfit保留到left[i]
,逆序遍歷一遍並把每個階段的maxProfit保留到right[i]
中。
上面代碼只進行了一次遍歷,驗證了下面代碼的left[i]
和right[i]
就是第i天前一次交易最大收益
和第i天後一次交易最大收益
時間復雜度:O(n)
class Solution { public: int maxProfit(vector<int> &prices) { int s = prices.size(); if (s < 2) return 0; int preMaxvalue[s], postMaxvalue[s]; memset(preMaxvalue, 0, sizeof(preMaxvalue)); memset(postMaxvalue, 0, sizeof(postMaxvalue)); int curMin = prices[0]; for (int i = 1; i < s; i++) { curMin = min(curMin, prices[i]); preMaxvalue[i] = max(preMaxvalue[i - 1], prices[i] - curMin); } int curMax = prices[s - 1]; for (int i = s - 2; i >= 0; i--) { curMax = max(curMax, prices[i]); postMaxvalue[i] = max(postMaxvalue[i + 1], curMax - prices[i]); } int maxProfit = 0; for (int i = 0; i < s; i++) { maxProfit = max(maxProfit, preMaxvalue[i] + postMaxvalue[i]); } return maxProfit; } };
[leetcode]123.買賣股票的最佳時機3