这是我参与2022首次更文挑战的第20天,活动详情查看:2022首次更文挑战
题目
309. 最佳买卖股票时机含冷冻期
解析
对于每一天而言,无非可以做以下三种选择:
- 可以买入
- 这要求:上一次交易是两天以前
- 可以卖出
- 这要求:手上有一只股票
- 什么都不做
而什么都不做有以下几种情况:
- 可以买入,但是不买入
- 可以卖出,但是不卖出
- 处于冷静期
那么根据前后关系,可以拟出以下流程图:
graph LR
1[前一天]-->卖出1-->第二天-什么都不做
1-->买入2-->第二天-卖出
买入2-->第二天-什么都不做
1-->什么都不做-->第二天-买入
什么都不做-->第二天-卖出
什么都不做-->第二天-s
那么,其实每一天结束的时候,都有以下的状态:
- 持有一只股票【1】
- 没有股票,且今天没有交易【2】
- 冷静期【3】
对于后面的一天来说,状态就可以由上一天的状态来推算:
- 持有一只股票,可以从上一天的【1】和【2】+买入今天股票推得(持有和昨天相同的股票,或者昨天没有持有股票而今天买入了)
- 没有股票,可以从昨天的【2】和【3】推得
- 冷静期的话,就属于今日一定要从【1】推得了(昨天已持有股票,今日必须卖出)。
同时,需要注意到一点:
- 对于某一天而言,实际上对于题目结果而言,具体买入和卖出哪一天的股票是没有意义的,我们仅想知道最终的最大利润。
根据上述描述,就可以写出下面的代码:
public int maxProfit2(int[] prices) {
int n = prices.length;
//dp[i][0]:有股票 dp[i][1]:没股票 dp[i][2]:今天卖出
int with = -prices[0],without = 0,coolDown = 0;
for (int i = 1; i < n; i++) {
int curW = Math.max(without - prices[i],with);
int curWO = Math.max(without,coolDown);
coolDown = with + prices[i];
with = curW;
without = curWO;
}
return Math.max(with,Math.max(without,coolDown));
}
最终结果:
执行用时: 0 ms
内存消耗: 39.2 MB