day51 ● 309.最佳买卖股票时机含冷冻期 ● 714.买卖股票的最佳时机含手续费

112 阅读4分钟

题目描述:

309.最佳买卖股票时机含冷冻期

给定一个整数数组,其中第 i 个元素代表了第 i 天的股票价格 。​

设计一个算法计算出最大利润。在满足以下约束条件下,你可以尽可能地完成更多的交易(多次买卖一支股票):

  • 你必须在每个交易日结束前,都持有一支股票。
  • 卖出股票后,你无法在第二天买入股票 (即冷冻期为 1 天)。

示例:

输入: [1,2,3,0,2] 输出: 3 解释: 对于给定的输入数组, 在第 i 天买入股票, 在第 j 天卖出股票, 利润为 j - i - 1 (注意: 这里的 i 和 j 都是从 0 开始计数的)。

714.买卖股票的最佳时机含手续费

给定一个整数数组 prices,其中第 i 个元素代表了第 i 天的股票价格 ;非负整数 fee 代表了交易股票的手续费用。

你可以无限次地完成交易,但是你每次交易都需要付手续费。如果你已经购买了一个股票,在卖出它之前你就不能再购买股票了。

返回获得利润的最大值。

示例:

输入: prices = [1, 3, 2, 8, 4, 9], fee = 2 输出: 8 解释: 能够达到的最大利润:
在此处买入 prices[0] = 1,在此处卖出 prices[3] = 8,利润 = 8 - 1 - 2 = 5 。 注意利润不能是 7,因为卖出价格需要大于买入价格。

技术报告:

一、最佳买卖股票时机含冷冻期

动态规划是解决这个问题的最佳方法。定义状态转移方程为:

dp[i][0] 表示第 i 天交易完后手里没有股票的最大利润,dp[i][1] 表示第 i 天交易完后手里持有一支股票的最大利润,dp[i][2] 表示第 i 天交易完后手里持有股票,且处于冷冻期的最大利润。

状态转移方程如下:

dp[i][0] = max(dp[i-1][0], dp[i-1][2]) dp[i][1] = max(dp[i-1][1], dp[i-1][0]-prices[i]) dp[i][2] = dp[i-1][1]+prices[i]

其中,dp[i][0] 表示第 i 天不持有股票,有两种情况:一是第 i-1 天也没有股票,dp[i-1][0];二是第 i-1 天持有股票但在第 i 天卖了,即 dp[i-1][2]。

dp[i][1] 表示第 i 天持有股票,有两种情况:一是第 i-1 天也持有股票,dp[i-1][1];二是第 i-1 天没有股票,但在第 i 天买了,即 dp[i-1][0]-prices[i]。

dp[i][2] 表示第 i 天持有股票,且处于冷冻期,只有一种情况:第 i-1 天持有股票,在第 i 天卖出,即 dp[i-1][1]+prices[i]。

最终结果为 dp[n-1][0],即最后一天交易完成后手里没有股票的最大利润。

Java 代码实现:


public int maxProfit(int[] prices) {
    if (prices == null || prices.length == 0) {
        return 0;
    }
    int n = prices.length;
    int[][] dp = new int[n][3];
    dp[0][0] = 0;
    dp[0][1] = -prices[0];
    dp[0][2] = 0;
    for (int i = 1; i < n; i++) {
        dp[i][0] = Math.max(dp[i-1][0], dp[i-1][2]);
        dp[i][1] = Math.max(dp[i-1][1], dp[i-1][0]-prices[i]);
        dp[i][2] = dp[i-1][1]+prices[i];
    }
    return Math.max(dp[n-1][0], dp[n-1][2]);
}

二、买卖股票的最佳时机含手续费

同样利用动态规划的思想,定义状态转移方程为:

dp[i][0] 表示第 i 天交易完后手里没有股票的最大利润,dp[i][1] 表示第 i 天交易完后手里持有一支股票的最大利润。

状态转移方程如下:

dp[i][0] = max(dp[i-1][0], dp[i-1][1]+prices[i]-fee) dp[i][1] = max(dp[i-1][1], dp[i-1][0]-prices[i])

其中,dp[i][0] 表示第 i 天不持有股票,有两种情况:一是第 i-1 天也没有股票,dp[i-1][0];二是第 i-1 天持有股票但在第 i 天卖了,即 dp[i-1][1]+prices[i]-fee。

dp[i][1] 表示第 i 天持有股票,有两种情况:一是第 i-1 天也持有股票,dp[i-1][1];二是第 i-1 天没有股票,但在第 i 天买了,即 dp[i-1][0]-prices[i]。

最终结果为 dp[n-1][0],即最后一天交易完成后手里没有股票的最大利润。

Java 代码实现:


public int maxProfit(int[] prices, int fee) {
    if (prices == null || prices.length == 0) {
        return 0;
    }
    int n = prices.length;
    int[][] dp = new int[n][2];
    dp[0][0] = 0;
    dp[0][1] = -prices[0];
    for (int i = 1; i < n; i++) {
        dp[i][0] = Math.max(dp[i-1][0], dp[i-1][1]+prices[i]-fee);
        dp[i][1] = Math.max(dp[i-1][1], dp[i-1][0]-prices[i]);
    }
    return dp[n-1][0];
}

以上就是两道题的解法和代码实现,希望能够对大家有所帮助。