代码随想录二刷Day38
今日任务
理论基础
509.斐波那契数
70.爬楼梯
746.使用最小花费爬楼梯
语言:Go
理论基础
动态规划五部曲:
- 确定dp数组及下标的含义
- 确定递归公式
- dp数组初始化
- 确定遍历顺序
- 举例推导dp数组
509. 斐波那契数
链接:https://leetcode.cn/problems/fibonacci-number/
func fib(n int) int {
//1.确定dp数组及下标含义:dp[i]表示斐波那契数列第i个结果是dp[i]
//2.确定递归公式:dp[i] = dp[i-1] + dp[i-2]
//3.dp数组初始化:dp[0]=0, d[1]=1
//4.确定遍历顺序:从小到大
//5.举例推导dp数组
if n <= 1 {
return n
}
var dp []int
dp = append(dp, 0)
dp = append(dp, 1)
for i := 2; i <= n; i++ {
dp = append(dp, dp[i - 1] + dp[i - 2])
}
return dp[n]
}
改进:不必维护一个数组,只维护两个值即可
func fib(n int) int {
if n <= 1 {
return n
}
num1 := 0
num2 := 1
for i := 2; i <= n; i++ {
tmp := num1 + num2
num1 = num2
num2 = tmp
}
return num2
}
70. 爬楼梯
链接:https://leetcode.cn/problems/climbing-stairs/
func climbStairs(n int) int {
//1.明确dp数组及下标含义:dp[i]表示到第i个台阶共有dp[i]种走法
//2.明确递归公式:dp[i]=dp[i-1]+dp[i-2]
//3.dp数组初始化
//4.明确dp数组遍历顺序
//5.举例推导dp数组
//可以直接优化成只维护两个数字
num1 := 1 //爬到第一个台阶有1种爬法
num2 := 2 //爬到第二个台阶有2种爬法
if n <= 2 {
return n
}
for i := 3; i <= n; i++ {
tmp := num1 + num2
num1 = num2
num2 = tmp
}
return num2
}
746. 使用最小花费爬楼梯
链接:https://leetcode.cn/problems/min-cost-climbing-stairs/
func min(x, y int) int {
if x < y {
return x
} else {
return y
}
}
func minCostClimbingStairs(cost []int) int {
//1.确定dp数组及下标含义:dp[i]表示爬到第i个台阶的最低花费
//2.确定dp递归公式:dp[i]=min(dp[i-2]+cost[i-2],dp[i-1]+cost[i-1])
//3.初始化dp:dp[0]=0, dp[1]=0
//4.确定dp遍历顺序:从小到大
//5.举例推导dp数组验证
var dp []int
dp = append(dp, 0) //爬到第0个台阶不需要花费
dp = append(dp, 0) //爬到第1个台阶也不需要花费
for i := 2; i <= len(cost); i++ {
dp = append(dp, min(dp[i - 2] + cost[i - 2], dp[i - 1] + cost[i - 1]))
}
return dp[len(dp) - 1]
}
改进
func min(x, y int) int {
if x < y {
return x
} else {
return y
}
}
func minCostClimbingStairs(cost []int) int {
num1 := 0 //爬到第0个台阶不需要花费
num2 := 0 //爬到第1个台阶也不需要花费
for i := 2; i <= len(cost); i++ {
tmp := min(num1 + cost[i - 2], num2 + cost[i - 1])
num1 = num2
num2 = tmp
}
return num2
}