算法系列:动态规划
动规五部曲:
- 确定dp数组和下标的含义
- 确定递推公式
- dp数组初始化
- 确定遍历顺序
- 打印递推数组
题目1:509. 斐波那契数
//动规
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.爬楼梯
// @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.使用最小花费爬楼梯
// 动规
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]
}
}