持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第23天,点击查看活动详情
LeetCode 75 —— 746. 使用最小花费爬楼梯
一、题目描述:
给你一个整数数组 cost ,其中 cost[i] 是从楼梯第 i 个台阶向上爬需要支付的费用。一旦你支付此费用,即可选择向上爬一个或者两个台阶。
你可以选择从下标为 0 或下标为 1 的台阶开始爬楼梯。
请你计算并返回达到楼梯顶部的最低花费。
示例 1:
输入:cost = [10,15,20]
输出:15
解释:你将从下标为 1 的台阶开始。
- 支付 15 ,向上爬两个台阶,到达楼梯顶部。 总花费为 15 。
示例 2:
输入:cost = [1,100,1,1,1,100,1,1,100,1]
输出:6
解释:你将从下标为 0 的台阶开始。
- 支付 1 ,向上爬两个台阶,到达下标为 2 的台阶。
- 支付 1 ,向上爬两个台阶,到达下标为 4 的台阶。
- 支付 1 ,向上爬两个台阶,到达下标为 6 的台阶。
- 支付 1 ,向上爬一个台阶,到达下标为 7 的台阶。
- 支付 1 ,向上爬两个台阶,到达下标为 9 的台阶。
- 支付 1 ,向上爬一个台阶,到达楼梯顶部。
- 总花费为 6 。
提示:
2 <= cost.length <= 1000
0 <= cost[i] <= 999
来源:力扣(LeetCode)
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
二、思路分析:
-
这道题考察了什么思想?你的思路是什么?
看到这道题目,我的第一思路因为每次只能爬一阶或者两阶,所以获取cost[i]之后cost[i+1]和cost[i+2]的值,然后比较这两个的大小,取小的路径走,这样就会出大问题:
func minCostClimbingStairs(cost []int) int { c := 0 i := 0 for i < len(cost)-1 { c += cost[i] fmt.Println(c,i) if i+2 < len(cost) && i+1 < len(cost){ if cost[i+1] < cost[i+2] { i++ }else{ i+=2 } }else if i+2 >= len(cost) && i+1 < len(cost){ i++ } } return c }当输入为
[10,15,20]时,会出现走10、15、20的路径。于是,我想到用动态规划来解决此道题。设置数组dp,其dp[i]放置的是从开始到当前下标i的最小花费。可以将下标0和1作为初始阶梯,即dp[0]和dp[1]都等于0。
所以有状态转移方程:
dp[i] = min(dp[i-1] + cost[i-1] , dp[i-2]+cost[i-2])
然后按顺序计算dp中的每一项的值,最终得到dp[n]到达楼顶的最小花费。
func minCostClimbingStairs(cost []int) int { n := len(cost) dp := make([]int, n+1) for i := 2; i <= n; i++ { if dp[i-1]+cost[i-1] < dp[i-2]+cost[i-2]{ dp[i] = dp[i-1]+cost[i-1] }else { dp[i] = dp[i-2]+cost[i-2] } } return dp[n] } -
做题的时候是不是一次通过的,遇到了什么问题,需要注意什么细节?
不是啊!!!!!
我太菜了!!!!!
宝宝菜菜,要抱抱!
注意思路要对啊,大佬!!!
-
有几种解法,哪种解法时间复杂度最低,哪种解法空间复杂度最低,最优解法是什么?其他人的题解是什么,谁的效率更好一些?用不同语言实现的话,哪个语言速度最快?
二维数组解法,还是动态规划,这道题就是典型的动态规划入门题。
func minCostClimbingStairs(cost []int) int { dp := make([][]int,len(cost)) dp[0] = []int{cost[0],cost[0]} dp[1] = []int{cost[0],cost[1]} for i := 2;i < len(cost);i++ { dp[i] = []int{ dp[i-1][1], min(dp[i-1][0] + cost[i],dp[i-1][1] + cost[i]), } } return min(dp[len(cost)-1][0],dp[len(cost)-1][1]) } func min(a,b int) int { if a > b { return b } return a } 作者:purelightme 链接:https://leetcode.cn/problems/min-cost-climbing-stairs/solution/dong-tai-gui-hua-er-wei-golang-yu-da-jia-neht/ 来源:力扣(LeetCode) 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。上述代码的时间复杂度和空间复杂度都是 O(n)。注意到当 i≥2 时,dp[i]只与dp[i-1]和dp[i-2]有关,因此可以使用滚动数组的思想,将空间复杂度优化到 O(1)。
func minCostClimbingStairs(cost []int) int { n := len(cost) pre, cur := 0, 0 for i := 2; i <= n; i++ { pre, cur = cur, min(cur+cost[i-1], pre+cost[i-2]) } return cur } func min(a, b int) int { if a < b { return a } return b } 作者:LeetCode-Solution 链接:https://leetcode.cn/problems/min-cost-climbing-stairs/solution/shi-yong-zui-xiao-hua-fei-pa-lou-ti-by-l-ncf8/ 来源:力扣(LeetCode) 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
三、AC 代码:
func minCostClimbingStairs(cost []int) int {
n := len(cost)
dp := make([]int, n+1)
for i := 2; i <= n; i++ {
if dp[i-1]+cost[i-1] < dp[i-2]+cost[i-2]{
dp[i] = dp[i-1]+cost[i-1]
}else {
dp[i] = dp[i-2]+cost[i-2]
}
}
return dp[n]
}
四、总结:
典型的动态规划题目!可以使用滚动数组的思想,将空间复杂度优化到 O(1)。
模板来源:
作者:掘金酱
来源:稀土掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。