力扣-123买卖股票的最佳时机III(dp)

力扣-123买卖股票的最佳时机III

1、题目

123. 买卖股票的最佳时机 III

给定一个数组,它的第 i 个元素是一支给定的股票在第 i 天的价格。

设计一个算法来计算你所能获取的最大利润。你最多可以完成 两笔 交易。

注意:你不能同时参与多笔交易(你必须在再次购买前出售掉之前的股票)。

示例 1:

输入:prices = [3,3,5,0,0,3,1,4]
输出:6
解释:在第 4 天(股票价格 = 0)的时候买入,在第 6 天(股票价格 = 3)的时候卖出,这笔交易所能获得利润 = 3-0 = 3 。
     随后,在第 7 天(股票价格 = 1)的时候买入,在第 8 天 (股票价格 = 4)的时候卖出,这笔交易所能获得利润 = 4-1 = 3 。

2、分析

  1. 题目。这题与122买卖股票的最佳时机II的区别就是,限制了买卖次数为2。这种dp题就是状态一类的划分,看如何划分比较方便和合适,上一题明显就是两个状态,那么这个当然就可以想成4个状态:

    1.第一,二次拥有(买入)状态(存在多天的股票的状态)

    • 前一次未拥有,本次买入
    • 前一次已拥有,本次无操作

    2.第一,二次未拥有(卖出)状态

    • 前一天未拥有,本次无操作
    • 前一天拥有,本次卖出
  2. 设置dp数组,根据上面分析,我们共有4个状态,所以我们设置二维数组,dp【i】【5】,1-4分别对应第一次的买卖,和第二次的买卖。这里之所以设置了长度为5,是因为后面进行状态1第一次买入的时候,不需要设置0开始的初始值,因为默认数组值就是0。

  3. 遍历。同样是需要前一个dp,所以我们是从前往后遍历的。

3、代码及注释

class Solution {
    public int maxProfit(int[] prices) {
        // 1.4个状态,1第一次买入,2第一次卖出,3第二次买入,4第二次卖出
        int n = prices.length;
        int[][] dp = new int[n][5];
		
        // 2.第一二次的买入
        dp[0][1] = -prices[0];
        dp[0][3] = -prices[0];

        for (int i = 1; i < n; i++){
            dp[i][1] = Math.max(dp[i - 1][1], dp[i - 1][0] - prices[i]);
            dp[i][2] = Math.max(dp[i - 1][2], dp[i - 1][1] + prices[i]);
            dp[i][3] = Math.max(dp[i - 1][3], dp[i - 1][2] - prices[i]);
            dp[i][4] = Math.max(dp[i - 1][4], dp[i - 1][3] + prices[i]);
        }

        return dp[n - 1][4];
    }
}

4、练习

力扣题目链接:123. 买卖股票的最佳时机 III

你可能感兴趣的:(算法与数据结构,leetcode,动态规划,算法)