算法 - 动规09(Swift版本)

71 阅读2分钟

题目1:188.买卖股票的最佳时机IV

讲解
leetcode

// 二维数组
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.最佳买卖股票时机含冷冻期

讲解
leetcode

状态多加一个冷冻期就好。

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.买卖股票的最佳时机含手续费

讲解
leetcode

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)
    }
}

汇总

截屏2024-11-26 12.05.19.png