LeetCode 309. 买卖股票的最佳时机含冷冻期
题目链接:309. 买卖股票的最佳时机含冷冻期 - 力扣(LeetCode)
所谓的冷冻期,就是卖了股票后的第二天不能买入该股票(股票上的N+2,N+1是今天卖明天能买),所以影响到的是递推公式中买股票的情况,也就是状态转移时候第i天的买入是从第i-2天的状态转移过来的。
代码:
#python #含冷冻期版本
class Solution:
def maxProfit(self, prices: List[int]) -> int:
if not prices or len(prices) <= 1:
return 0
n = len(prices)
dp = [[0, 0] for _ in range(n)]
dp[0][0] = -prices[0]
dp[0][1] = 0
for i in range(1, n):
dp[i][0] = max(dp[i-1][0], dp[i-2][1] - prices[i]) #从i-2转移过来
dp[i][1] = max(dp[i-1][1], dp[i-1][0] + prices[i])
return dp[-1][1]
/java
public class Solution {
public int maxProfit(int[] prices) {
if (prices == null || prices.length <= 1) {
return 0;
}
int n = prices.length;
int[][] dp = new int[n][2];
dp[0][0] = -prices[0]; // 第一天买入股票
dp[0][1] = 0; // 第一天不持有股票
for (int i = 1; i < n; i++) {
// 第i天不持有股票,可能是第i-1天就不持有,或者是第i天卖出
dp[i][1] = Math.max(dp[i - 1][1], dp[i - 1][0] + prices[i]);
// 第i天持有股票,有两种情况:
// 1. 第i-1天就持有股票,由于冷冻期的限制,不能从第i-1天卖出再买入
// 2. 第i天买入股票,那么第i-2天必须是不持有股票的状态
// 注意:当i == 1时,dp[i - 2][1]实际上会访问dp[-1][1],但Java中数组索引不能为负,因此需要做额外处理
if (i == 1) {
dp[i][0] = Math.max(dp[i - 1][0], -prices[i]);
} else {
dp[i][0] = Math.max(dp[i - 1][0], dp[i - 2][1] - prices[i]);
}
}
// 最后一天不持有股票时的最大利润
return dp[n - 1][1];
}
}
LeetCode 714. 买卖股票的最佳时机含手续费
题目链接:714. 买卖股票的最佳时机含手续费 - 力扣(LeetCode)
这道题很简单,其实就是在每次卖出的时候都减去该笔交易的手续费就好,每一笔手续费都是固定值fee,所以状态转移方程是dp[i][1] = dp[i-1][0] + prices[i] -fee。
代码:
#python #带手续费的版本
class Solution:
def maxProfit(self, prices: List[int], fee: int) -> int:
if not prices or len(prices) < 1:
return 0
n = len(prices)
dp = [[0, 0] for _ in range(n)]
dp[0][0] = - prices[0]
dp[0][1] = 0
for i in range(1, n):
dp[i][0] = max(dp[i - 1][0], dp[i - 1][1] - prices[i]) #初始值,与前一个i的卖出状态下买入股票做比较,取其大值
dp[i][1] = max(dp[i - 1][1], dp[i - 1][0] + prices[i] - fee) #要么是没有利润,要么就是前一个i的拥有股票状态下卖出当前的价格,再减去手续费,取其大值
return dp[-1][1]
/java
public class Solution {
public int maxProfit(int[] prices, int fee) {
if (prices == null || prices.length < 2) {
return 0;
}
int n = prices.length;
int[][] dp = new int[n][2];
dp[0][0] = -prices[0]; // 第一天买入股票
dp[0][1] = 0; // 第一天不持有股票
for (int i = 1; i < n; i++) {
// 第i天持有股票,要么是第i-1天就持有股票,要么是第i天买入股票
dp[i][0] = Math.max(dp[i - 1][0], dp[i - 1][1] - prices[i]);
// 第i天不持有股票,要么是第i-1天就不持有股票,要么是第i天卖出股票
dp[i][1] = Math.max(dp[i - 1][1], dp[i - 1][0] + prices[i] - fee);
}
// 最后一天不持有股票时的最大利润
return dp[n - 1][1];
}
}