[LeetCode]最佳买卖股票时机含冷冻期

136 阅读2分钟

这是我参与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