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