java题解"股票市场交易策略优化" | 豆包MarsCode AI刷题

280 阅读3分钟

题目描述

给定一个整数数组,其中第 i 个元素代表了第 i 天的股票价格。设计一个算法计算出最大利润。在满足以下约束条件下,你可以尽可能地完成更多的交易(多次买卖一支股票):

  1. 你不能同时参与多笔交易(你必须在再次购买前出售掉之前的股票)。
  2. 卖出股票后,你无法在第二天买入股票(即冷冻期为 1 天)。

输入格式

一个数组,表示每天的股票价格。

数据约束

  • 数组长度 1 <= n <= 10000
  • 每天的价格 0 <= prices[i] <= 10000

输出格式

最大的收益数值。

示例

输入样例

[1, 2]
[2, 1]
[1, 2, 3, 0, 2]
[2, 3, 4, 5, 6, 7]
[1, 6, 2, 7, 13, 2, 8]

输出样例

1
0
3
5
12

解题思路

为了计算在有冷冻期的情况下买卖股票的最大利润,我们可以使用动态规划来解决这个问题。我们需要维护三个状态变量来记录不同状态下的最大利润:

  1. hold:持有股票的最大利润。
  2. sell:当天卖出股票的最大利润。
  3. rest:当天休息(不买卖)的最大利润。

具体的状态转移方程如下:

  • hold:今天持有的股票可以是昨天持有的股票,或者是昨天休息今天买入的股票。
    • hold = max(hold, rest - prices[i])
  • sell:今天卖出的股票只能是昨天持有的股票。
    • sell = hold + prices[i]
  • rest:今天休息可以是昨天休息,或者是昨天卖出股票。
    • rest = max(rest, sell)

初始化

  • hold 初始化为 -prices[0],因为第一天买入股票的成本是负的。
  • sellrest 初始化为 0,因为第一天不可能卖出股票或休息。

状态更新

我们需要在遍历价格数组的过程中不断更新这三个状态变量。

代码实现

public class Main {
    public static int solution(int[] prices) {
        if (prices == null || prices.length == 0) {
            return 0;
        }

        int n = prices.length;
        int hold = -prices[0]; // 第一天持有股票的成本
        int sell = 0;          // 第一天不可能卖出股票
        int rest = 0;          // 第一天不可能休息

        for (int i = 1; i < n; i++) {
            int prevHold = hold;
            int prevSell = sell;
            int prevRest = rest;

            // 更新 hold 状态
            hold = Math.max(prevHold, prevRest - prices[i]);

            // 更新 sell 状态
            sell = prevHold + prices[i];

            // 更新 rest 状态
            rest = Math.max(prevRest, prevSell);
        }

        // 最终的最大利润应该是 sell 或 rest 中的最大值
        return Math.max(sell, rest);
    }

    public static void main(String[] args) {
        // 测试用例
        System.out.println(solution(new int[]{1, 2}) == 1);
        System.out.println(solution(new int[]{2, 1}) == 0);
        System.out.println(solution(new int[]{1, 2, 3, 0, 2}) == 3);
        System.out.println(solution(new int[]{2, 3, 4, 5, 6, 7}) == 5);
        System.out.println(solution(new int[]{1, 6, 2, 7, 13, 2, 8}) == 12);
    }
}

代码解释

  1. 初始化

    • hold 初始化为 -prices[0],因为第一天买入股票的成本是负的。
    • sellrest 初始化为 0,因为第一天不可能卖出股票或休息。
  2. 状态转移

    • hold:今天持有的股票可以是昨天持有的股票,或者是昨天休息今天买入的股票。Math.max(prevHold, prevRest - prices[i])
    • sell:今天卖出的股票只能是昨天持有的股票。prevHold + prices[i]
    • rest:今天休息可以是昨天休息,或者是昨天卖出股票。Math.max(prevRest, prevSell)
  3. 最终结果

    • 最终的最大利润应该是 sellrest 中的最大值,因为最后一天要么卖出股票,要么休息。

通过这种方式,我们可以有效地计算出在有冷冻期的情况下买卖股票的最大利润。