其他分享
首页 > 其他分享> > LeetCode 0123 Best Time to Buy and Sell Stock III

LeetCode 0123 Best Time to Buy and Sell Stock III

作者:互联网

原题传送门

1. 题目描述

2. Solution 1

1、思路分析
DP
1> 状态定义: dp[k][i] 表示在第i天进行第k笔交易能获得的最大利润。
2> 边界: dp[k][i] = {0}
3> 状态转移:
若在第i天没有进行交易,则最大利润为前一天的最大利润。即dp[k][i] = dp[k][i-1]。
若在第j天买入了股票,j = [0, ..., i-1],然后在第i天卖出,利润为: prices[i] - prices[j] + dp[k-1][j-1]。
实际上,j也可以取到i,此时,利润为prices[i] - prices[j] + dp[k-1][i]。
综上: dp[k, i] = max(dp[k, i-1], prices[i] - prices[j] + dp[k-1, j-1]), j=[0..i-1]

2、代码实现

package Q0199.Q0123BestTimetoBuyandSellStockIII;

/*
    It's not difficult to get the DP recursive formula:
    dp[k, i] = max(dp[k, i-1], prices[i] - prices[j] + dp[k-1, j-1]), j=[0..i-1]
    For k transactions, on i-th day,
    if we don't trade then the profit is same as previous day dp[k, i-1];
    and if we bought the share on j-th day where j=[0..i-1], then sell the share on i-th day then the profit is
    prices[i] - prices[j] + dp[k-1, j-1] .
    Actually j can be i as well. When j is i, the one more extra item
    prices[i] - prices[j] + dp[k-1, j] = dp[k-1, i] looks like we just lose one chance of transaction.
    I see someone else use the formula dp[k, i] = max(dp[k, i-1], prices[i] - prices[j] + dp[k-1, j]), where the
    last one is dp[k-1, j] instead of dp[k-1, j-1]. It's not the direct sense, as if the share was bought on j-th
    day, then the total profit of previous transactions should be done on (j-1)th day. However, the result based on
    that formula is also correct, because if the share was sold on j-th day and then bought again, it is the same if
    we didn't trade on that day.
    So the straightforward implementation is:
*/
public class Solution1 {
    public int maxProfit(int[] prices) {
        if (prices.length == 0) return 0;
        int[][] dp = new int[3][prices.length];
        for (int k = 1; k <= 2; k++) {
            for (int i = 1; i < prices.length; i++) {
                int min = prices[0];
                for (int j = 1; j <= i; j++)
                    min = Math.min(min, prices[j] - dp[k - 1][j - 1]);
                dp[k][i] = Math.max(dp[k][i - 1], prices[i] - min);
            }
        }
        return dp[2][prices.length - 1];
    }
    // Time complexity is O(kn^2), space complexity is O(kn).
}

3、复杂度分析
时间复杂度: O(kn^2)
空间复杂度: O(kn)

3. Solution 2

1、思路分析
Solution 1是进行k次交易的通用方法,本题中k=2,所以把数组拆成变量,可以降低空间复杂度。

2、代码实现

package Q0199.Q0123BestTimetoBuyandSellStockIII;

// In this case, K is 2. We can expand the array to all named variables:
public class Solution4 {
    public int maxProfit(int[] prices) {
        int buy1 = Integer.MAX_VALUE, buy2 = Integer.MAX_VALUE;
        int sell1 = 0, sell2 = 0;

        for (int price : prices) {
            buy1 = Math.min(buy1, price);
            sell1 = Math.max(sell1, price - buy1);
            buy2 = Math.min(buy2, price - sell1);
            sell2 = Math.max(sell2, price - buy2);
        }
        return sell2;
    }
}

3、复杂度分析
时间复杂度: O(n)
空间复杂度: O(1)

标签:Sell,Buy,0123,int,复杂度,th,prices,day,dp
来源: https://www.cnblogs.com/junstat/p/16283226.html