算法 - 动规01(Swift版本)

93 阅读2分钟

算法系列:动态规划

基础知识

动规五部曲:

  1. 确定dp数组和下标的含义
  2. 确定递推公式
  3. dp数组初始化
  4. 确定遍历顺序
  5. 打印递推数组

题目1:509. 斐波那契数

讲解
leetcode

//动规
class Solution {
    func fib(_ n: Int) -> Int {
        if n < 2 { return n }
        var dp = Array(repeating: 0, count: n + 1)
        dp[0] = 0
        dp[1] = 1
        for i in 2...n { 
            dp[i] = dp[i - 1] + dp[i - 2]   
        }
        return dp[n]
    }
}


// 空间省略
class Solution {
    func fib(_ n: Int) -> Int {
        if n < 2 { return n }
        var dp = Array(repeating: 0, count: n + 1)
        dp[0] = 0
        dp[1] = 1
        for i in 2...n {
            (dp[0], dp[1]) = (dp[1], dp[0] + dp[1])
        }
        return dp[1]
    }
}

题目2:70.爬楼梯

讲解
leetcode

// @lc code=start
class Solution {
    func climbStairs(_ n: Int) -> Int {
        if n <= 2 { return n } 
        var dp = Array(repeating: 0, count: n + 1)
        dp[1] = 1
        dp[2] = 2
        for i in 3...n {
            dp[i] = dp[i - 1] + dp[i - 2]
        }
        return dp[n]
    }
}
// @lc code=end

题目3:746.使用最小花费爬楼梯

讲解
leetcode

// 动规
class Solution {
    func minCostClimbingStairs(_ cost: [Int]) -> Int {
        // dp含义:第i阶所需要最小花费
        // 所以既然是楼顶,那就是cost数组的最后一个元素 + 1
        var dp = Array(repeating: 0, count: cost.count + 1)
        // 第一阶梯 和 第二阶梯 按照题目理解不用花费,初始化为0
        for i in 2...cost.count {
            dp[i] = min(dp[i - 1] + cost[i - 1], dp[i - 2] + cost[i - 2])
        }
        return dp[cost.count]
    }
}

// 节省空间
class Solution {
    func minCostClimbingStairs(_ cost: [Int]) -> Int {
        // dp含义:第i阶所需要最小花费
        // 所以既然是楼顶,那就是cost数组的最后一个元素 + 1
        var dp = Array(repeating: 0, count: 2)
        // 第一阶梯 和 第二阶梯 按照题目理解不用花费,初始化为0
        for i in 2...cost.count {
            (dp[1] ,dp[0]) = (min(dp[1] + cost[i - 1], dp[0] + cost[i - 2]), dp[1])
        }
        return dp[1]
    }
}