相信很多小伙伴刷题的时候面对力扣上近两千到题目,感觉无从下手,我花费半年时间整理的Github学习项目:leetcode刷题指南,不仅有详细经典题目刷题顺序而且对应题解来排好了,难点还有视频讲解,按照list一道一道刷就可以了,绝对是最强攻略!

746. 使用最小花费爬楼梯

题目链接:https://leetcode-cn.com/problems/min-cost-climbing-stairs/

数组的每个下标作为一个阶梯,第 i 个阶梯对应着一个非负数的体力花费值 cost[i](下标从 0 开始)。

每当你爬上一个阶梯你都要花费对应的体力值,一旦支付了相应的体力值,你就可以选择向上爬一个阶梯或者爬两个阶梯。

请你找出达到楼层顶部的最低花费。在开始时,你可以选择从下标为 0 或 1 的元素作为初始阶梯。

示例 1:

输入:cost = [10, 15, 20]
输出:15
解释:最低花费是从 cost[1] 开始,然后走两步即可到阶梯顶,一共花费 15 。
示例 2:

输入:cost = [1, 100, 1, 1, 1, 100, 1, 1, 100, 1]
输出:6
解释:最低花费方式是从 cost[0] 开始,逐个经过那些 1 ,跳过 cost[3] ,一共花费 6 。

提示:

  • cost 的长度范围是 [2, 1000]。
  • cost[i] 将会是一个整型数据,范围为 [0, 999] 。

思路

这道题目可以说是昨天动态规划:爬楼梯的花费版本。

注意题目描述:每当你爬上一个阶梯你都要花费对应的体力值,一旦支付了相应的体力值,你就可以选择向上爬一个阶梯或者爬两个阶梯

所以示例1中只花费一个15 就可以到阶梯顶,最后一步可以理解为 不用花费。

读完题大家应该知道指定需要动态规划的,贪心是不可能了。

  1. 确定dp数组以及下标的含义

使用动态规划,就要有一个数组来记录状态,本题只需要一个一维数组dp[i]就可以了。

dp[i]的定义:第i个台阶所花费的最少体力为dp[i]

对于dp数组的定义,大家一定要清晰!

  1. 确定递推公式

可以有两个途径得到dp[i],一个是dp[i-1] 一个是dp[i-2]

那么究竟是选dp[i-1]还是dp[i-2]呢?

一定是选最小的,所以dp[i] = min(dp[i - 1], dp[i - 2]) + cost[i];

注意这里为什么是加cost[i],而不是cost[i-1],cost[i-2]之类的,因为题目中说了:每当你爬上一个阶梯你都要花费对应的体力值

  1. dp数组如何初始化

根据dp数组的定义,dp数组初始化其实是比较难的,因为不可能初始化为第i台阶所花费的最少体力。

那么看一下递归公式,dp[i]由dp[i-1],dp[i-2]推出,既然初始化所有的dp[i]是不可能的,那么只初始化dp[0]和dp[1]就够了,其他的最终都是dp[0]dp[1]推出。

所以初始化代码为:

vector<int> dp(cost.size());
dp[0] = cost[0];
dp[1] = cost[1];
  1. 确定遍历顺序

最后一步,递归公式有了,初始化有了,如何遍历呢?

本题的遍历顺序其实比较简单,简单到很多同学都忽略了思考这一步直接就把代码写出来了。

因为是模拟台阶,而且dp[i]又dp[i-1]dp[i-2]推出,所以是从前到后遍历cost数组就可以了。

但是稍稍有点难度的动态规划,其遍历顺序并不容易确定下来

例如:01背包,都知道两个for循环,一个for遍历物品嵌套一个for遍历背包容量,那么为什么不是一个for遍历背包容量嵌套一个for遍历物品呢? 以及在使用一维dp数组的时候遍历背包容量为什么要倒叙呢?

这些都是遍历顺序息息相关。当然背包问题后续「代码随想录」都会重点讲解的!

  1. 举例推导dp数组

拿示例2:cost = [1, 100, 1, 1, 1, 100, 1, 1, 100, 1] ,来模拟一下dp数组的状态变化,如下:

如果大家代码写出来有问题,就把dp数组打印出来,看看和如上推导的是不是一样的。

以上分析完毕,整体C++代码如下:

// 版本一
class Solution {
public:int minCostClimbingStairs(vector<int>& cost) {vector<int> dp(cost.size());dp[0] = cost[0];dp[1] = cost[1];for (int i = 2; i < cost.size(); i++) {dp[i] = min(dp[i - 1], dp[i - 2]) + cost[i];}// 注意最后一步可以理解为不用花费,所以取倒数第一步,第二步的最少值return min(dp[cost.size() - 1], dp[cost.size() - 2]);}
};
  • 时间复杂度:O(n)
  • 空间复杂度:O(n)

还可以优化空间复杂度,因为dp[i]就是由前两位推出来的,那么也不用dp数组了,C++代码如下:

// 版本二
class Solution {
public:int minCostClimbingStairs(vector<int>& cost) {int dp0 = cost[0];int dp1 = cost[1];for (int i = 2; i < cost.size(); i++) {int dpi = min(dp0, dp1) + cost[i];dp0 = dp1; // 记录一下前两位dp1 = dpi;}return min(dp0, dp1);}
};
  • 时间复杂度:O(n)
  • 空间复杂度:O(1)

当然我不建议这么写,能写出版本一就可以了,直观简洁!

在后序的讲解中,可能我会忽略这种版本二的写法,大家只要知道有这么个写法就可以了哈。

总结

大家可以发现这道题目相对于 昨天的动态规划:爬楼梯有难了一点,但整体思路是一样。

从动态规划:斐波那契数到 动态规划:爬楼梯再到今天这道题目,录友们感受到循序渐进的梯度了嘛。

每个系列开始的时候,都有录友和我反馈说题目太简单了,赶紧上难度,但也有录友和我说有点难了,快跟不上了。

其实我选的题目都是有目的性的,就算是简单题,也是为了练习方法论,然后难度都是梯度上来的,一环扣一环。

但我也可以随便选来一道难题讲呗,这其实是最省事的,不用管什么题目顺序,看心情找一道就讲。

难的是把题目按梯度排好,循序渐进,再按照统一方法论把这些都串起来,哈哈,所以大家不要催我哈,按照我的节奏一步一步来就行啦。

学算法,认准「代码随想录」,没毛病!

我是程序员Carl,可以找我组队刷题,也可以在B站上找到我,关注公众号代码随想录来和上万录友一起打卡学习算法,来看看,你会发现相见恨晚!

如果感觉对你有帮助,不要吝啬给一个

「代码随想录」746. 使用最小花费爬楼梯【动态规划】力扣详解!相关推荐

  1. 85. Leetcode 746. 使用最小花费爬楼梯 (动态规划-基础题)

    给你一个整数数组 cost ,其中 cost[i] 是从楼梯第 i 个台阶向上爬需要支付的费用.一旦你支付此费用,即可选择向上爬一个或者两个台阶.你可以选择从下标为 0 或下标为 1 的台阶开始爬楼梯 ...

  2. 代码随想录算法训练营第三十八天 | 509. 斐波那契数、70. 爬楼梯、746. 使用最小花费爬楼梯。

    Leetcode 509. 斐波那契数 题目链接:509. 斐波那契数 class Solution {public:int fib(int n) {if(n <= 1)return n;int ...

  3. 746. 使用最小花费爬楼梯 golang 动态规划

    746. 使用最小花费爬楼梯 746. 使用最小花费爬楼梯 数组的每个索引做为一个阶梯,第 i个阶梯对应着一个非负数的体力花费值 costi. 每当你爬上一个阶梯你都要花费对应的体力花费值,然后你可以 ...

  4. leetcode - 746. 使用最小花费爬楼梯

    746. 使用最小花费爬楼梯 -------------------------------------- 数组的每个索引做为一个阶梯,第 i个阶梯对应着一个非负数的体力花费值 cost[i] (索引 ...

  5. 力扣算法 509. 斐波那契数 70. 爬楼梯 746. 使用最小花费爬楼梯

    学习内容 力扣算法 509. 斐波那契数 70. 爬楼梯 746. 使用最小花费爬楼梯 具体内容 509. 斐波那契数 斐波那契数,通常用 F(n) 表示,形成的序列称为 斐波那契数列 .该数列由 0 ...

  6. LeetCode-动态规划基础题-746. 使用最小花费爬楼梯

    描述 746.使用最小花费爬楼梯 数组的每个下标作为一个阶梯,第 i 个阶梯对应着一个非负数的体力花费值 cost[i](下标从 0 开始). 每当你爬上一个阶梯你都要花费对应的体力值,一旦支付了相应 ...

  7. LeetCode Algorithm 746. 使用最小花费爬楼梯

    746. 使用最小花费爬楼梯 Ideas 首先确定题目类型,爬楼梯问题,并且给定了状态转移的限制,其实就已经可以确定状态转移方程了. 然后题目说可以从下标为0或下标为1的台阶开始爬,所以我们可以定义两 ...

  8. D38| DP理论基础 509. 斐波那契数 70. 爬楼梯 746. 使用最小花费爬楼梯

    DP理论基础 重要知识点: 1.动规和贪心的区别:动规是由前一个状态推导出来的,而贪心是局部直接选最优的 2.动规五部曲: 1)确定dp数组(dp table)以及下标的含义 2)确定递推公式 3)d ...

  9. [每日一题]746. 使用最小花费爬楼梯

    [每日一题]746. 使用最小花费爬楼梯 数组的每个索引作为一个阶梯,第 i个阶梯对应着一个非负数的体力花费值 costi. 每当你爬上一个阶梯你都要花费对应的体力花费值,然后你可以选择继续爬一个阶梯 ...

  10. Java实现 LeetCode 746 使用最小花费爬楼梯(递推)

    746. 使用最小花费爬楼梯 数组的每个索引做为一个阶梯,第 i个阶梯对应着一个非负数的体力花费值 costi. 每当你爬上一个阶梯你都要花费对应的体力花费值,然后你可以选择继续爬一个阶梯或者爬两个阶 ...

最新文章

  1. php把数组转换成对象,php怎么将数组转换成对象
  2. 推荐系统笔记:矩阵分解+基于邻居的模型
  3. mysql auto position_MHA-Failover(GTID,Auto_Position=0)
  4. 前端学习(3164):react-hello-react之添加todoList
  5. AllenAI 发布万能问答系统 MACAW!各类题型样样精通,性能大幅超越 GPT-3!
  6. (数据库系统概论|王珊)第四章数据库安全性-第二、三、四、五、六节:数据库安全性控制
  7. 一文讲清,MySQL中的二级索引
  8. underscorejs-min学习
  9. [Note] FrameFab Interesting Cut Results
  10. 任学堂说科技:穿越计算机迷雾,从零开始构建计算机
  11. 酷狗与鸿蒙系统,酷狗音乐2020最新版|酷狗音乐鸿蒙版安卓版下载 v10.2.7 - 跑跑车安卓网...
  12. 广告联盟,拿什么拯救博客?
  13. ECS的简单入门(二):Entity
  14. 谷歌学术403:某URL没有权限访问
  15. 一份诚恳的互联网找工作总结和感想(附:怎样花两年时间去面试一个人)
  16. LVOOP(二)、面向对象概念演示
  17. 全网手机号码归属地号段总数量70W条
  18. java Itextpdf 图片转pdf并压缩下载至浏览器
  19. 国密SM9算法C++实现之八:密钥交换算法
  20. 【2018.07.29】(深度优先搜索/回溯)学习DFS算法小记

热门文章

  1. bzoj2705 [SDOI2012]Longge的问题
  2. Linux下安装与使用本地的perl模块
  3. 一天一小段js代码(no.4)
  4. SPOJ 196 动态规划
  5. Inno Setup 操作XML
  6. Ubuntu下安装Adobe Reader的中文语言包
  7. yum安装Apache2.4
  8. BM25算法的python实现
  9. 个人技能总结7--Apache服务器反向代理,负载均衡,热备份+Tomcat配置
  10. RabbitMQ三种Exchange