LeetCode:309. 买卖股票的最佳时机含冷冻期 - 力扣(LeetCode)
1.思路
同一支股票允许多次买卖。有持有/卖出/保持卖出/冷冻期四种状态,持有可分为:前一天持有/前一天冷冻期当天买入持有/前一天保持卖出当天买入持有。不持有:卖出/保持卖出/冷冻期。卖出:前一天持有且当天卖出。保持卖出:前一天卖出后续不操作/前一天保持卖出。冷冻期:前一天卖出当天处于冷冻期。
2.代码实现
class Solution {
public int maxProfit(int[] prices) {
// 持有:当天买入股票/前一天买入股票一直没有操作 dp[i][0]
// 不持有1:卖出状态:①当天卖出; dp[i][1] = dp[i - 1][0] + prices[i];
// ②保持卖出状态:前天卖出度过一天冷冻期,或者2两天及以前卖出之后一直没操作 dp[i][2] = Math.max(dp[i - 1][1], dp[i - 1][2])
// 不持有2:冷冻期:前一天卖出且当天冷冻期 dp[i][3] = dp[i - 1][2]
int[][] dp = new int[prices.length][4];
// 初始化
dp[0][0] = - prices[0];
dp[0][1] = 0;
dp[0][2] = 0;
dp[0][3] = 0;
for (int i = 1; i < prices.length; i++) {
// 持有股票
dp[i][0] = Math.max(dp[i - 1][0], Math.max(dp[i - 1][2] - prices[i], dp[i - 1][3] - prices[i]));
// 卖出股票
dp[i][1] = dp[i - 1][0] + prices[i];
// 保持卖出股票:前一天就保持卖出股票得状态/前一天卖出股票后续不操作
dp[i][2] = Math.max(dp[i - 1][2], dp[i - 1][1]);
// 冷冻期
dp[i][3] = dp[i - 1][1];
}
return Math.max(dp[prices.length - 1][1], dp[prices.length - 1][2]);
}
}
3.复杂度分析
时间复杂度:O(n).
空间复杂度:O(n).
LeetCode:
1.思路
每日得股票有两种状态,持有和不持有。持有:前一天就持有当天保持/当天买入持有。不持有:前一天不持有/当天卖出不持有。如果存在最大利润大于0,一定在不持有得状态。
2.代码实现
class Solution {
public int maxProfit(int[] prices, int fee) {
// 买入持有状态:前一天持有/前一天不持有且当天持有 dp[i][0] = Math.max(dp[i - 1][1] - prices[i], dp[i - 1][0])
// 卖出不持有状态:前一天卖出状态/当天卖出 dp[i][1] = Math.max(dp[i - 1][1], dp[i - 1][0] + prices[i])
int[][] dp = new int[prices.length][2];
dp[0][0] = - prices[0];
dp[0][1] = 0;
for (int i = 1; i < prices.length; i++) {
dp[i][0] = Math.max(dp[i - 1][1] - prices[i], dp[i - 1][0]); // 持有
dp[i][1] = Math.max(dp[i - 1][1], dp[i - 1][0] + prices[i] - fee);
}
return dp[prices.length - 1][1];
}
}
3.复杂度分析
时间复杂度:O(n).
空间复杂度:O(n).