【leetcode】股票买卖系列总结
股票買賣系列總結
股票買賣系列的題目在面試中還是比較經典的,這里對這一系列做一些簡單的總結。
1. 只允許買賣一次
假設股票價格序列為(3, 5, 7, 3, 8, 1)
動態(tài)規(guī)劃。整個過程中的行為選擇有3種,買/賣/無操作。
用\(dp[i]\)表示第\(i\)天的行為是”賣出“時,能得到的最大收益。顯然,我們固定了賣出的時間,只要在這個時間點之前的時間中選擇股票價格比最小的時候買入,就可以確定\(dp[i]\)的值。
所以我們可以遍歷價格序列,cur_min不斷更新以記錄當前時間點之前的股票最低價格,所以\(dp[i] = max(0, prices[i]-cur\_min)\),最后所有dp[i]中的最大值就是只進行一次買賣能得到的最大利潤。可以在求\(dp[i]\)的同時用一個變量來記錄其最大值。
因為\(dp[i]\)只用到一次,所以沒必要開一個數組專門來存儲。
class Solution { public:int maxProfit(vector<int>& prices) {// 只允許最多一次交易 求最大收益// 記錄當前最小 cur_min dp[i]表示在第i天賣出的最大收益if(prices.size()<=1) return 0;int cur_min = prices[0], res = 0;for(int i=1; i<prices.size(); i++){res = max(prices[i]-cur_min, res);// dp[i] = prices[i] - cur_min;cur_min = min(cur_min, prices[i]);}return res;} };2. 不限制買賣次數
假設股票價格序列為(1, 2, 3, 4, 5)。其實這是一個特殊情況,我們可以在第0天買入,然后在最后一天賣出。此時最大收益就是4。
我們也可以在第0天買入,第一天賣出。第一天買入,第二天賣出。。。這樣的結果和上面是一樣的,最大收益都是4。
所以,對于比較常規(guī)的情況,比如說(7, 6, 3, 4, 5),在第一天和第二天是不能買入的,因為,之后找不到比當前價格更大的數了。另外的話,可以在3的時候買入,4的時候賣出,然后4又買入,5賣出。最后最大收益是2.
class Solution { public:int maxProfit(vector<int>& prices) {// 不限制股票的買賣次數// 只要是遇到比當前價格更高的就賣掉if(prices.size() <=1) return 0;int buy = INT_MAX, profit = 0;for(int i=0; i<prices.size(); i++){if(prices[i]<=buy) buy = prices[i];else{profit += prices[i]-buy;buy = prices[i];}}return profit;} };可以將上面代碼進行簡化:
class Solution { public:int maxProfit(vector<int>& prices) {if(prices.size() <=1) return 0;int buy = INT_MAX, profit = 0;for(int i=0; i<prices.size(); i++){if(prices[i] > buy) profit += prices[i] - buy;// 只有當當前價格大于假設買入的價格時,才進行賣出buy = prices[i];// 每次都在當前進行“假設”買入}return profit;} };3. 最多只能買賣2次
\(buy1\)表示在第\(i\)天進行第一次買入時可以獲得的最大收益
\(buy2\)表示在第\(i\)天進行第二次買入時可以獲得的最大收益
\(sell1\)表示在第\(i\)天進行第一次賣出時可以獲得的最大收益
\(sell2\)表示在第\(i\)天進行第二次賣出時可以獲得的最大收益
4. 有冷凍期不限制買賣次數
\(buy[i]\)表示第\(i\)天之前最后一次行為是buy時,最大的收益
\(sell[i]\)表示第\(i\)天之前最后一次行為是sell時,最大的收益
\(rest[i]\)表示第\(i\)天之前最后一次行為是冷凍rest時,最大的收益
\(buy[i] = max(buy[i-1], rest[i-1] - prices[i])\),max(第i天冷凍, 第i天是賣出)
\(sell[i] = max(sell[i-1], buy[i-1] + prices[i])\),max(第i天冷凍,第i天是買入)
\(rest[i] = max(rest[i-1], buy[i-1], sell[i-1])\)
class Solution { public:int maxProfit(vector<int>& prices) {// 有冷凍期 不限制買賣次數 但是賣完股票后有一天的冷凍期才能再接著買int n = prices.size();if(n<=1) return 0;vector<int> buy(n, INT_MIN), sell(n, INT_MIN), rest(n, INT_MIN);buy[0] = -prices[0];sell[0] = 0;rest[0] = 0;for(int i=1; i<n; i++){buy[i] = max(buy[i-1], rest[i-1]-prices[i]);sell[i] = max(sell[i-1], buy[i-1]+prices[i]);rest[i] = max(rest[i-1], max(buy[i-1], sell[i-1]));}return max(buy[n-1], max(sell[n-1], rest[n-1]));} };轉載于:https://www.cnblogs.com/Elaine-DWL/p/11202859.html
總結
以上是生活随笔為你收集整理的【leetcode】股票买卖系列总结的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: RabbitMQ操作代码封装
- 下一篇: 方差