题目1:188.买卖股票的最佳时机IV
// 二维数组
class Solution {
func maxProfit(_ k: Int, _ prices: [Int]) -> Int {
// 同买卖股票三 系列。 需要记录每天的 第x操作的买卖状态
// dp[i][j] 第i天的 第j种状态。
// 状态 0:不操作 1:第1天买入 2“第2天卖出 3:第2天买入 ...
if prices.count == 1 { return 0 }
var dp = Array(repeating: Array(repeating: 0, count: 2 * k + 1), count: prices.count)
for i in 1...(2*k) where i % 2 == 1 {
dp[0][i] = -prices[0]
}
for i in 1..<prices.count {
for j in 1...(2*k) where j % 2 == 1 {
// 买入
dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - 1] - prices[i])
// 卖出
dp[i][j + 1] = max(dp[i - 1][j + 1], dp[i - 1][j] + prices[i])
}
}
return dp[prices.count - 1][2 * k]
}
}
// 一维滚动数组
class Solution {
func maxProfit(_ k: Int, _ prices: [Int]) -> Int {
// 同买卖股票三 系列。 需要记录每天的 第x操作的买卖状态
// dp[i][j] 第i天的 第j种状态。
// 状态 0:不操作 1:第1天买入 2“第2天卖出 3:第2天买入 ...
if prices.count == 1 { return 0 }
var dp = Array(repeating: 0, count: 2 * k + 1)
for i in 1...(2*k) where i % 2 == 1 {
dp[i] = -prices[0]
}
for i in 1..<prices.count {
for j in (1...(2*k)).reversed() where j % 2 == 1 {
// 卖出
dp[j + 1] = max(dp[j + 1], dp[j] + prices[i])
// 买入
dp[j] = max(dp[j], dp[j - 1] - prices[i])
}
}
return dp[2 * k]
}
}
题目2:309.最佳买卖股票时机含冷冻期
状态多加一个冷冻期就好。
0:持有 1:不持有(冷冻期) 2:不持有(非冷冻期)
// @lc code=start
class Solution {
func maxProfit(_ prices: [Int]) -> Int {
// 既然多了个冷冻期, 那么将冷冻期的状态加进来。
// 0:持有 1:不持有(冷冻期) 2:不持有(非冷冻期)
if prices.count == 1 { return 0 }
var dp = Array(repeating: Array(repeating: 0, count: 3), count: prices.count)
dp[0][0] = -prices[0]
for i in 1..<prices.count {
// 持有: 昨天就持有、昨天不持有 今天买入
dp[i][0] = max(dp[i - 1][0], dp[i - 1][2] - prices[i])
// 不持有(冷冻期):今天刚卖
dp[i][1] = dp[i - 1][0] + prices[i]
// 不持有(非冷冻期):昨天不持有(非冷冻期)、昨天不持有(冷冻期)
dp[i][2] = max(dp[i - 1][2], dp[i - 1][1])
}
return max(dp[prices.count - 1][1], dp[prices.count - 1][2])
}
}
// @lc code=end
题目3:714.买卖股票的最佳时机含手续费
class Solution {
func maxProfit(_ prices: [Int], _ fee: Int) -> Int {
if prices.count == 1 { return 0 }
typealias status = (hold: Int, unhold: Int)
var dp = Array(repeating: status(0, 0), count: prices.count)
dp[0].hold = -prices[0]
for i in 1..<prices.count {
// 持有
dp[i].hold = max(dp[i - 1].hold, dp[i - 1].unhold - prices[i])
// 不持有:卖出时付费即可
dp[i].unhold = max(dp[i - 1].unhold, dp[i - 1].hold + prices[i] - fee)
}
return max(dp[prices.count - 1].unhold, dp[prices.count - 1].hold)
}
}