leetcode 309. Best Time to Buy and Sell Stock with Cooldown
来源:互联网 发布:python经纬度画轨迹图 编辑:程序博客网 时间:2024/06/07 02:39
Say you have an array for which the ith element is the price of a given stock on day i.
Design an algorithm to find the maximum profit. You may complete as many transactions as you like (ie, buy one and sell one share of the stock multiple times) with the following restrictions:
- You may not engage in multiple transactions at the same time (ie, you must sell the stock before you buy again).
- After you sell your stock, you cannot buy stock on next day. (ie, cooldown 1 day)
Example:
prices = [1, 2, 3, 0, 2]maxProfit = 3transactions = [buy, sell, cooldown, buy, sell]
dp[ i ] 存储了从 i ~ prices.length 的时间段内的最大收益。i 从大到小来慢慢算出 dp[i]。
public int maxProfit(int[] prices) {int n=prices.length;if(n==0){return 0;}int[] dp=new int[n];dp[n-1]=0;for(int begin=n-2;begin>=0;begin--){int maxCount=0;//以begin为起点时间段内的最大收益for(int end=begin+1;end<n;end++){//依次遍历begin后面的时间点int count=0;if(prices[end]<=prices[begin]){count=dp[end];}else{//如果 end股票值>begin股票值,说明可以在begin买入,end抛出if(end+2<n){count=prices[end]-prices[begin]+dp[end+2];}else{count=prices[end]-prices[begin];}}if(count>maxCount){maxCount=count;}}dp[begin]=maxCount;}return dp[0];}大神们用了有限状态机模型来解决。
这个问题的三个状态分别是: buy
, sell
, rest
. 这里 rest
意味着在当天没有任何交易。这个有限状态机有可能在任意的这三个状态中停止。我们可以简化为2个状态:buy
, sell
:buy状态指当前最后一笔交易是买入,比如[0,1,2],在0时买入,在1时不交易,此时1的状态仍然是buy状态。sell状态指当前最后一笔交易是卖出,比如[0,2,1],在0时买入,2时卖出,此时2和1的状态都是sell状态。
这里显示了它们之间的关系。
第 i 天的状态为buy状态,有两种可能:“在 i-2 天状态为卖出,在第 i 天买入”(单单仅 第 i-1 天状态为卖出 不够,必须是第 i-2 天状态也是卖出 才行“)或者 “在第 i-1 天状态为买入,第 i 天保持不变”。
第 i 天的状态为sell状态,有两种可能:“在 i-1 天状态为买入,在第 i 天卖出” 或者 “在第 i-1 天状态为卖出,第 i 天保持不变”。
buy[i] = max(sell[i-2]-price, buy[i-1])sell[i] = max(buy[i-1]+price, sell[i-1])
考虑到day i
依赖于day i-1
和 i-2
的状态,我们可以进一步简化我们的解决方案,
- 让
b2, b1, b0
来表达buy[i - 2], buy[i - 1], buy[i]
- 让
s2, s1, s0
来表达sell[i - 2], sell[i - 1], sell[i]
因此公式转化为:
b0 = Math.max(b1, s2 - prices[i]);s0 = Math.max(s1, b1 + prices[i]);
我们定义
i = 0
的初始状态
- 可以为买入状态 ,在
i = 0
处买入,收益为-prices[0]
. - 可以为卖出状态,在
i = 0
处为卖出状态,意思就是不做任何交易,收益为0
.
这是代码:
public int maxProfit(int[] prices) { if(prices == null || prices.length <= 1) return 0; int b0 = -prices[0], b1 = b0; int s0 = 0, s1 = 0, s2 = 0; for(int i = 1; i < prices.length; i++) { b0 = Math.max(b1, s2 - prices[i]); s0 = Math.max(s1, b1 + prices[i]); b1 = b0; s2 = s1; s1 = s0; } return s0;}
如果还是不懂,可以看大神的原版英文解释哦:1. Define States
To represent the decision at index i:
buy[i]
: Maximum profit which end with buying on dayi
or end with buying on a day beforei
and takes rest until the dayi
since then.sell[i]
: Maximum profit which end with selling on dayi
or end with selling on a day beforei
and takes rest until the dayi
since then.
To clarify:
- Till index
i
, the buy / sell action must happen and must be the last action. It may not happen at indexi
. It may happen ati - 1, i - 2, ... 0
. - In the end
n - 1
, returnsell[n - 1]
. Apparently we cannot finally end up with a buy. In that case, we would rather take a rest atn - 1
. - For special case no transaction at all, classify it as
sell[i]
, so that in the end, we can still returnsell[n - 1]
. Thanks @alex153 @kennethliaoke @anshu2.
2. Define Recursion
buy[i]
: To make a decision whether to buy ati
, we either take a rest, by just using the old decision ati - 1
, or sell at/beforei - 2
, then buy ati
, We cannot sell ati - 1
, then buy ati
, because of cooldown.sell[i]
: To make a decision whether to sell ati
, we either take a rest, by just using the old decision ati - 1
, or buy at/beforei - 1
, then sell ati
.
So we get the following formula:
buy[i] = Math.max(buy[i - 1], sell[i - 2] - prices[i]); sell[i] = Math.max(sell[i - 1], buy[i - 1] + prices[i]);
3. Optimize to O(1) Space
DP solution only depending on i - 1
and i - 2
can be optimized using O(1) space.
- Let
b2, b1, b0
representbuy[i - 2], buy[i - 1], buy[i]
- Let
s2, s1, s0
representsell[i - 2], sell[i - 1], sell[i]
Then arrays turn into Fibonacci like recursion:
b0 = Math.max(b1, s2 - prices[i]);s0 = Math.max(s1, b1 + prices[i]);
4. Write Code in 5 Minutes
First we define the initial states at i = 0
:
- We can buy. The max profit at
i = 0
ending with a buy is-prices[0]
. - We cannot sell. The max profit at
i = 0
ending with a sell is0
.
Here is my solution. Hope it helps!
public int maxProfit(int[] prices) { if(prices == null || prices.length <= 1) return 0; int b0 = -prices[0], b1 = b0; int s0 = 0, s1 = 0, s2 = 0; for(int i = 1; i < prices.length; i++) { b0 = Math.max(b1, s2 - prices[i]); s0 = Math.max(s1, b1 + prices[i]); b1 = b0; s2 = s1; s1 = s0; } return s0;}
- leetcode Best Time to Buy and Sell Stock with Cooldown
- LeetCode Best Time to Buy and Sell Stock with Cooldown
- Leetcode: Best Time to Buy and Sell Stock with Cooldown
- [LeetCode]Best Time to Buy and Sell Stock with Cooldown
- Leetcode Best Time to Buy and Sell Stock with Cooldown
- leetcode - Best Time to Buy and Sell Stock with Cooldown
- LeetCode:Best Time to Buy and Sell Stock with Cooldown
- leetcode Best Time to Buy and Sell Stock with Cooldown
- Leetcode Best Time to Buy and Sell Stock with Cooldown
- LeetCode:Best Time to Buy and Sell Stock with Cooldown
- LeetCode--Best Time to Buy and Sell Stock with Cooldown
- 309.Best Time to Buy and Sell Stock with Cooldown
- 309. Best Time to Buy and Sell Stock with Cooldown
- 309. Best Time to Buy and Sell Stock with Cooldown
- 309. Best Time to Buy and Sell Stock with Cooldown
- 309. Best Time to Buy and Sell Stock with Cooldown
- 309. Best Time to Buy and Sell Stock with Cooldown
- 309. Best Time to Buy and Sell Stock with Cooldown
- Spark和Hive集成使用时mysql驱动包无法加载解决办法
- X is intended for a x86_64 architecture问题解决
- 设计模式之策略模式
- Ubuntu17.04安装Docker17.06后配置国内(Docker中国官方)镜像加速
- (01背包扩展) 算法提高 金明的预算方案
- leetcode 309. Best Time to Buy and Sell Stock with Cooldown
- LSTM
- (转)单例模式详解
- Python 解析CSV
- 钱数
- 【c++】vector简要用法
- Java运算符优先级
- 对抗生成网络(Generative Adversarial Net)
- 2017年7月8日 东方在新书发布会上的发言稿