代码随想录Day42

Posted 末誓

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了代码随想录Day42相关的知识,希望对你有一定的参考价值。

今天开始正式进入动态规划部分,不过动态规划在我开始写博客之前已经做过一部分,但当时归当时,现在应当重新以更加细致的方式学习动规。

509.斐波那契数

斐波那契数 (通常用 F(n) 表示)形成的序列称为 斐波那契数列 。该数列由 0 和 1 开始,后面的每一项数字都是前面两项数字的和。也就是:

F(0) = 0,F(1) = 1
F(n) = F(n - 1) + F(n - 2),其中 n > 1
给定 n ,请计算 F(n) 。

示例 1:

输入:n = 2
输出:1
解释:F(2) = F(1) + F(0) = 1 + 0 = 1

思路:

1.显然在题目和示例中都已经告诉了我们dp数组的公式,dp[i] = dp[i - 1] + dp[i - 2],然后初始化dp[0] = 1, dp[1] = 1。

2.但实际上本题可以进一步优化,因为公式中涉及到的实际上都是三个常数,因此我们可以只使用三个整型变量进行不断地迭代就可。

class Solution 
public:
    int fib(int n) 
         int a = 0, b = 1 , c = 1;
         for(int i = 0; i < n; i++)
             int sum = b + c;
             a = b;
             b = c;
             c = sum;
         

         return a;
    
;

启发:

1.本题初次接触可能都会想到使用递归的方法,但递归在n较大时无论是时间复杂度还是因为递归函数调用的栈的空间都会比较大。通过题目已经给出的公式可以想到通过动态规划进行优化。

2.另一个优化的点在于dp数组,因为我们实际上只要找到第n个数就可以了,我们没有必要使用额外的空间来记录第n个数之前的所有数字,但要推导出第n个数又不得不需要前面的所有数字的帮助,因此我们可以用三个整型变量来代替公式中的三个数,进行不断的迭代就可以了。

需要注意的是最后返回的变量时a,a在一开始初始化为0就是因为题目中给出的n的取值范围是可以取0的,因此a初始化为0代表第0个斐波那契数字,迭代完毕后自然a代表的就是第n为斐波那契数字。

70.爬楼梯

假设你正在爬楼梯。需要 n 阶你才能到达楼顶。

每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢?

示例 1:

输入:n = 2
输出:2
解释:有两种方法可以爬到楼顶。
1. 1 阶 + 1 阶
2. 2 阶

思路:

1.本题与斐波那契数列是同样的思路,但因为涉及到一个爬楼梯的场景,所以需要时刻提醒自己:要求的是方法数,不是跳了几次

class Solution 
public:
    int climbStairs(int n) 
        long long a = 0, b = 1, c = 2;
        for(int i = 0; i < n; i++)
            long long sum = b + c;
            a = b;
            b = c;
            c = sum;
        
        return a;
    
;

启发:

1.本题尽管代码与上一道题基本一致,但还是有需要注意的点,首先是本题的初始化,dp[1] = 1, dp[2] = 2,或许会疑惑,dp[0]到底该初始化为多少?尽管题目中n>=1,但还是会想要考虑一下这点。

但实际上纠结于dp[0]初始化为多少没有意义,因为既然n>=1了,无论a初始化为0还是1,for循环都会至少执行一次,而循环中并不涉及到将a代入公式中进行计算,因此a无论初始化为0还是1都不影响最终结果

2.其次是关于变量类型的问题,在上一题中n最大只到30,而本题中最大到45,如果只用int类型变量会溢出,因此改为long long类型

746.使用最小花费爬楼梯

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

你可以选择从下标为 0 或下标为 1 的台阶开始爬楼梯。

请你计算并返回达到楼梯顶部的最低花费。

示例 1:

输入:cost = [10,15,20]
输出:15
解释:你将从下标为 1 的台阶开始。
- 支付 15 ,向上爬两个台阶,到达楼梯顶部。
总花费为 15 。

思路:

1.到了本题终于开始有一点发生变化了,首先我们来确定dp数组的下标i和dp[i]的含义。显然i就是第i层楼梯,dp[i]就是到达第i层楼梯需要消耗的费用。但需要注意的一点是楼顶实际上是下标为cost.size()的地方。

2.接下来是对dp数组进行初始化,需要注意根据题目的描述,支付费用后才向上爬楼梯,而一开始我们就已经直接在0或者1的位置,因此到达0和1的楼梯我们是不需要花费体力的,因此dp[0]和dp[1]都应当初始化为0

3.然后是递推公式,要想到达当前楼梯i可以有两种方式,一种是从i - 1楼梯跳一步,一种是从i - 2的楼梯跳两步,因此dp[i]只可能从dp[i - 1] + cost[i - 1]和dp[i - 2] + cost[i - 2]中取得,而题目要求的是最小花费,因此我们取最小值即可。

class Solution 
public:
    int minCostClimbingStairs(vector<int>& cost) 
        vector<int>dp(cost.size() + 1);
        dp[0] = 0, dp[1] = 0;

        for(int i = 2; i <= cost.size(); i++)
            dp[i] = min(dp[i - 1] + cost[i - 1], dp[i - 2] + cost[i - 2]);
        

        return dp[cost.size()];
    
;

启发:

1.本题难度不算高,但依然需要注意题目中的各种细节,尤其是楼顶的位置和初始化的想法。

代码随想录算法公开课!

关注代码随想录的录友,基本都是跟着代码随想录一起刷题的。

目前代码随想录的内容是完全开放在代码随想录网站,Github,和Gitee上,同时也出版了《代码随想录》纸质版

这套刷题顺序和题解帮助了非常多的录友。

而现在我打算将《代码随想录》上的内容,全部由我以视频的方式再讲解一遍。

这些视频内容,我完全免费开放在B站上

即:《代码随想录》算法公开课正式开更

链接直达:《代码随想录》算法公开课

B站同名:代码随想录

目前已经讲完了《代码随想录》中 数组,链表,哈希表,字符串章节,栈与队列将在本周讲完。

二叉树,回溯算法,贪心,动态规划 也讲了前几节。 所以整体内容已经算是全的,现在已经在每周几道题目的速度去更新。

从文字讲解到视频讲解,从网站内容到纸质出版,都是为了不断满足录友们的学习需求所做的迭代

算法课长什么样

让我们来看看 《代码随想录》算法公开课 长什么样:

大家可以发现,右边的视频目录是和《代码随想录》的顺序一样一样的,也就是书中的每道题目,我都有对应的讲解,本周将会更新完栈与队列,下周开始完善二叉树系列视频。

那么算法视频质量如何呢?

其实我说好,不算好,大家说好才是真的好。

质量到底如何,大家可以去B站上去(B站同名:代码随想录)。

其实很多培训机构,包括出版社,想找我针对《代码随想录》做付费算法视频,而且报酬很不错,但我都婉拒了。

感觉做成公开课,有利于广大的录友们,也更有利于 “代码随想录” 这五个字的长远发展。 所以我决定还是做免费

而且 我的免费算法视频内容,要比绝大多数视频上大家付费的 算法视频课,算法训练营质量要高得多,视频课程基于《代码随想录》的刷题顺序来录制,会让视频内容非常系统,而不是东一块,西一块的。

关于质量如何,学习效果如果,大家可以去B站上去看(B站同名:代码随想录),有口皆碑!

录视频的难度

看过我的算法视频的录友应该能感受出来,我录制视频是 没有提示词的,没有任何提醒。

直接白板画流程图,手撕代码,这个难度其实是很大的, 因为脑子里要对算法题理解的特别清晰才能讲明白。

如果我换成任何其他形式来讲,其实都可以一边看着文案 一边讲的,那样会轻松非常多。

不过我是感觉这种讲课方式大家才能感受出我的思考过程,更能感受出和代码随想录文章不一样的地方,这也是很多录友看完我的B站算法视频感觉理解的更深刻了。

我的第一期算法视频「帮你把KMP算法学个通透!」,是我之前练习了很久,反复讲,反复写,最后才能讲出来的风格。

大家会发现国内向我这种方式讲解算法题的up非常少,几乎没有,因为难度是比较大的。

大家如果经常看油管的话,就会国外很多算法大佬讲算法,都是白板直接手撕代码的。



事实也说明,这种讲解方式是有利于大家理解的,只不过就是对up的讲解水平有很高的要求。

最后

话说录制这种课程,确实是要花费很多精力,而且全部免费开放给大家。

目前大家能搜到的 系统的算法视频,其实 质量都不算高,而且看视频确实对绝对多数录友来说,理解的会更加到位。

所以能让我更下去的动力,也就是大家的三连了,希望有一天 《代码随想录》算法公开课 会成为 大家学习编程,学习算法的必刷课程。

目前算法公开课全部发布在B站上,B站同名:代码随想录

链接直达:《代码随想录》算法公开课

最后,认准代码随想录,学习算法不迷路。加油💪🏻

以上是关于代码随想录Day42的主要内容,如果未能解决你的问题,请参考以下文章

代码随想录算法训练营第10天 | ● 理论基础 ● 232.用栈实现队列 ● 225. 用队列实现栈

代码随想录|day26|回溯算法part03● 39. 组合总和● 40.组合总和II● 131.分割回文串

代码随想录算法训练营day46|139.单词拆分 剑指Offer10-I.斐波那契数列 10-II.青蛙跳台阶问题

代码随想录|day38|动态规划part01● 理论基础 ● 509. 斐波那契数 ● 70. 爬楼梯 ● 746. 使用最小花费爬楼梯

贪心算法学习手册开放下载!!

代码随想录算法训练营第五十八天|739.每日温度496.下一个更大元素Ⅰ