尧图建网站 尧图建网站 YAOTU WEB BUILD 免费咨询
ARTICLE DETAIL

资讯详情

深耕网站建设与建站编程的一线实战洞察。

斐波那契数列面试全攻略:从递归到矩阵快速幂的解法演进

斐波那契数列面试全攻略:从递归到矩阵快速幂的解法演进 1. 为什么面试官十分钟爱斐波那契这题考察的根本不是背代码但凡准备过算法面试的人几乎都绕不开斐波那契数列。说实话我第一次看到这道题的时候也很无语——这不就是教科书里最基础的递归例子吗一个输入输出这么简单的题目凭什么在从初级到资深各个级别的程序员面试里反复出现后来我自己坐到面试官的位置上面了几百个候选人之后才真正想明白。斐波那契数列表面上是道题实际上是一把用来精准衡量候选人算法功底的标尺。面试官想要的从来不是“会不会背出递归解法”而是看你面对一个已知问题时的完整思考路径能不能从最朴素的解法出发通过分析时间和空间复杂度逐步推导出更优方案能不能意识到同一个问题背后隐藏着多种数学模型。具体拆开来讲这道题至少能考察六个维度的能力第一是递归思维。递归是很多算法的基础它能帮你把大规模问题拆成小规模问题而斐波那契恰好是最标准的递归结构——每一项依赖前两项。第二是动态规划思想。从递归到记忆化搜索再到迭代DP整条优化路径几乎就是一个简化版动态规划课程。第三是数学建模能力。当你把递推关系改写成矩阵形式、用快速幂求第N项时考的是你能不能从抽象的数列关系中发现矩阵乘法的结构。第四是复杂度分析能力。O(2^n)、O(n)、O(log n)这条复杂度下降曲线面试官希望听你亲口推演出来。第五是代码细节。边界条件、空间压缩、取模运算每一个细节都可能成为你的失分点。第六是沟通能力。你怎么向面试官解释你的思路、怎么回答“还有更好的办法吗”的追问这些都在考察真实的协作和表达水平。我在实际面试中遇到过一种典型情况候选人一上来就快速写完了记忆化递归代码很干净我追问了一句“你知道迭代解法怎么写吗”他也能马上写出来。但当我接着问“如果n是10的18次方呢还有办法吗”对方就愣住了。这道题真正的分水岭就在这里——你只是会写代码还是真的理解这组数字背后的数学规律。所以别小看这道题。它能在一面、二面甚至终面里被反复使用是因为同样的题目在不同深度的候选人面前会露出完全不同的层次。接下来我会把这套完整的解法演进路线拆开从最暴力的递归讲起一直讲到矩阵快速幂和通项公式每一步都给出代码和原理并标注出面试中最常踩的坑。2. 解法演进从暴力递归到矩阵快速幂的完整路线2.1 朴素递归三行代码背后的指数灾难很多初学者接触斐波那契数列的第一种实现就是递归。这个版本全宇宙的程序员都写过Python实现大概长这样def fib(n): if n 1: return n return fib(n - 1) fib(n - 2)代码确实简洁斐波那契数列的定义就是F(0)0, F(1)1, 之后每一项等于前两项之和递归几乎是定义本身的直接翻译。但如果你把这个函数扔去算n40就已经能明显感觉到卡顿n50的时候基本处于“等得想放弃”的状态。问题出在计算过程里存在大量重复子问题。算一下fib(6)的调用过程fib(6)要调fib(5)和fib(4)fib(5)要调fib(4)和fib(3)fib(4)要调fib(3)和fib(2)……层层叠叠展开之后你会发现同一个fib(3)被调用了好几次fib(2)被调用的次数更多。这种重复计算不是小事它的时间复杂度是指数级的。怎么精确分析这个递归的复杂度设T(n)表示计算fib(n)所需的基本操作次数那么T(n) T(n - 1) T(n - 2) O(1)因为你调一次fib(n)除了递归调用本身之外还做了一次加法。这个递推式跟斐波那契数列的递推式长得几乎一样解出来的结果就是T(n) O(2^n)。更具体一点如果把递归调用展开成树树的节点数就是实际函数调用次数这棵递归树的高度是n每个节点最多有两个分支所以总节点数按指数增长。空间复杂度也不容忽视。递归不是白调用的每深入一层就会在系统栈上压一个帧保存当前的参数和局部状态。算fib(n)时递归栈的最深深度是n所以空间复杂度是O(n)。对于Python默认的递归深度限制通常是1000左右n稍大一些就直接报RecursionError。我第一次带实习生的时候让他用这个写法跑fib(35)他在等待的时候还以为是电脑卡了其实不是是算法本身的复杂度在作祟。这个例子的教学意义恰恰在此它让抽象的时间复杂度变成了肉眼可见的卡顿让“指数爆炸”不再只是书本上的一个词。2.2 记忆化搜索给递归加一个草稿本自顶向下消除重复计算递归的问题很清楚同一个子问题被反复求解。那最自然的修法就是把已经算过的结果保存下来每次调用前先查一下缓存有就直接返回没有才算。这种思路叫记忆化搜索本质上就是自顶向下的动态规划。from functools import lru_cache lru_cache(maxsizeNone) def fib(n): if n 1: return n return fib(n - 1) fib(n - 2)Python里用lru_cache装饰器是最省事的做法它自动帮你维护一个哈希缓存。不用装饰器的话自己用字典写也很直观memo {0: 0, 1: 1} def fib(n): if n in memo: return memo[n] memo[n] fib(n - 1) fib(n - 2) return memo[n]这个版本的时间复杂度立刻降到了O(n)——每个n只会被真正计算一次后续再遇到都是直接查表。空间复杂度是O(n)因为你要存下0到n的所有结果。我在这里提醒一个细节记忆化搜索只是减少了重复计算它并没有消除递归本身的栈开销。在Python里用递归实现记忆化n稍微大一点比如n1000以上即使缓存已经把所有结果都存好了递归深度依然会成为瓶颈。很多人在这一步栽跟头以为记忆化之后就万事大吉了结果面试官随口让你写个n10000的用例当场就爆栈。所以记忆化搜索的正确身份是“过渡方案”它是从递归到迭代DP之间的桥梁是让你理解动态规划“记住结果避免重复计算”这个核心思想的最佳切入点但工程实践里它并不是最优的最终实现。2.3 迭代DP状态转移方程写清楚空间还能压缩到常数真正面试中最推荐的解法是迭代动态规划。既然每一项都只依赖前两项那我干脆从底部往上推用一个数组或者两个变量把中间结果滚动下去完全避免递归调用。先看用数组的版本状态转移方程就是dp[i] dp[i - 1] dp[i - 2]def fib(n): if n 1: return n dp [0] * (n 1) dp[1] 1 for i in range(2, n 1): dp[i] dp[i - 1] dp[i - 2] return dp[n]这个明确写出了动态规划三要素状态定义dp[i]表示斐波那契数列第i项、初始条件dp[0]0, dp[1]1、状态转移方程dp[i]dp[i-1]dp[i-2]。时间O(n)空间O(n)。但面试官到这里一定不会停他会追问你空间能不能再优化答案是当然能因为每一轮只用到了前两个数历史数组完全没有必要保留。用两个变量滚动更新就够了def fib(n): if n 1: return n prev2, prev1 0, 1 for _ in range(2, n 1): cur prev1 prev2 prev2, prev1 prev1, cur return prev1这时候时间O(n)空间O(1)。很多读者可能会问用一个长度为3的数组轮换和两个变量哪个更好懂对于面试场景我建议用两个变量因为代码更短而且“滚动”的思想对面试官来说更有说服力——空间压缩后的版本直接证明了你理解了状态转移过程而不是单纯背了模板。这里给一个我在面试里实际用过的口头解释框架“状态转移方程告诉我们计算第i项只需要第i-1项和第i-2项。第i-3项及更早的数据在计算完之后就再也不会被用到了所以不需要把它们留在内存里直接用两个变量滚动覆盖即可。”这样讲面试官一听就知道你不是背的是真的理解动态规划优化空间的核心逻辑。迭代DP的另一个隐性好处在Python里尤其明显它完全绕开了递归深度限制。不管n是几百万还是几千万理论上都能迭代算下去——只要别超时就行。2.4 矩阵快速幂从递推到矩阵乘法O(log n)求解超大n如果面试官开始加码“n可以是10的18次方你还能算吗”这就要祭出矩阵快速幂了。这是这道题真正的进阶分水岭能掌握它的人在面试中通常能在算法能力上拿到高分评价。核心思路是把斐波那契递推关系改写成矩阵乘法的形式。观察一下F(n) 1 * F(n-1) 1 * F(n-2) F(n-1) 1 * F(n-1) 0 * F(n-2)用矩阵表达就是[ F(n) ] [1 1] [F(n-1)] [ F(n-1) ] [1 0] * [F(n-2)]如果定义一个矩阵M [[1, 1], [1, 0]]那么[F(n) ] [F(1)] [F(n-1)] M^(n-1) * [F(0)]也就是说算斐波那契数列第n项本质上是算矩阵M的n-1次方再乘以初始向量。这个问题的关键就落在了“快速计算矩阵幂”上。矩阵幂有什么快的办法答案是快速幂也就是二分法。要算M^n如果n是偶数M^n (M^(n/2))^2如果n是奇数M^n (M^(n-1)) * M。这样每次把指数减半总共只需要O(log n)次矩阵乘法。Python实现如下def matrix_mul(a, b): return [ [a[0][0] * b[0][0] a[0][1] * b[1][0], a[0][0] * b[0][1] a[0][1] * b[1][1]], [a[1][0] * b[0][0] a[1][1] * b[1][0], a[1][0] * b[0][1] a[1][1] * b[1][1]] ] def matrix_pow(mat, power): # 初始化为单位矩阵 result [[1, 0], [0, 1]] while power 0: if power 1: result matrix_mul(result, mat) mat matrix_mul(mat, mat) power 1 return result def fib(n): if n 1: return n base [[1, 1], [1, 0]] result matrix_pow(base, n - 1) return result[0][0]这段代码把快速幂用在了矩阵上result初始化为单位矩阵相当于数字幂里的1每次循环中如果当前二进制位是1就把结果乘上当前矩阵然后矩阵自乘一次指数右移一位。循环次数是二进制位数也就是O(log n)。为什么单位矩阵是“矩阵世界里的1”因为任何矩阵乘以单位矩阵都等于它本身。这跟整数幂运算里x^01的逻辑完全一致是需要理解的一处细节。这个解法的复杂度是O(log n)时间上已经达成了理论上限——因为矩阵乘法本身常数级别很小2x2矩阵读入n就需要O(log n)时间所以不可能更快了。我自己在实际面试中见过一个有意思的画面候选人写了这个版本后面试官满意地点点头紧接着问了句“如果要求对1,000,000,007取模呢”。这就引出了下一个话题——大数处理。2.5 通项公式课堂上的数学优雅工程里的陷阱聊到这一步有些了解数论的同学可能会提斐波那契数列的通项公式也就是比内公式F(n) (φ^n - ψ^n) / √5其中φ (1 √5) / 2ψ (1 - √5) / 2。这个公式在数学上很优美但落实到代码上有大麻烦。√5是一个无理数在计算机里只能保存成浮点数当你计算φ^n的时候浮点误差会随着n不断累积。n比较小的时候可能还看得过去n到几十、上百就已经不精确了。更别说要处理取模运算的时候浮点方案几乎完全无法用。所以面试里遇到这题如果你主动提通项公式可以展示自己的数学储备但一定要随后补一句“浮点精度问题导致它不适合工程实现实际编码中我倾向用矩阵快速幂或者迭代DP”。这样既显得有深度又体现了工程判断力是很加分的做法。我把这个建议放在这里是因为它真的能帮你区分“懂数学”和“会写代码”。面试官真正想要的是在两者之间做出正确取舍的人。3. 面试现场实战拿到题之后每一步该怎么想、怎么说3.1 拿到题的第一步问清n的范围和边界条件很多候选人一听到“写斐波那契数列”手就跟条件反射一样飞向了键盘递归代码哗哗写完。这种做法的风险在于你没有把面试官隐含的考察点挖掘出来。正确姿势是开口先问清楚“n的范围是多少n从0开始还是从1开始如果n很大对结果有没有取模要求”这三个问题看似是澄清需求实际上每一条都在告诉面试官你有工程思维。n的范围决定了你选择什么算法n30和n10^18是完全不同的题目。n的起点决定了边界条件有些题目定义F(0)0有些定义F(1)1还有一些民间版本默认F(1)1且F(2)1但把索引从1开始。取模要求决定了中间计算要不要做模运算尤其在后序列计算中不做取模的话中间结果可能爆炸。我碰到过一个真实案例候选人写完了迭代DP我告诉他n比较大结果要对1000000007取模。他点点头说“好”然后在循环体里写了个if cur MOD: cur - MOD。这个做法对加法来说其实是安全的——因为cur prev1 prev2而prev1和prev2在上一轮都已经取过模了所以cur最大不超过2*MOD-2减一次就能回到模以内。但如果换成乘法运算就得用%运算符。这个细节如果面试官不提醒很多人会在压力下写错。3.2 先给朴素递归展示你的分析过程而不是直接甩最优解有人说面试算法题就应该直接给出最优解我觉得这是对面试本质的误解。面试官考察的不仅是你的储备更是你从0到1的推理过程。与其背个最优解直接落笔不如把复杂度分析完整走一遍让面试官看到你在“为什么要这么做”上想清楚了。建议节奏是这样的先写递归版本代码两秒钟搞定然后主动说“这个版本的时间复杂度是O(2^n)空间复杂度是O(n)原因是每次递归调用会产生两个分支递归树的节点数呈指数增长而且存在大量重复子问题。n到40就开始卡了所以它只适合教学演示。”然后立刻接上“既然有重复子问题我可以用记忆化把已经算过的结果缓存下来这样每个n只算一次时间复杂度降到O(n)空间O(n)。”紧接着再说“但递归还有栈深度问题Python默认递归深度只有1000n一大人就没了。所以更好的做法是改成迭代用一个滚动数组从底往上推时间O(n)空间O(1)。”这段话说完你就已经把递归→记忆化→迭代DP的完整进化路线讲完了面试官要是没叫停你就直接写迭代版本。如果面试官对你的速度很满意追问一句“还能更快吗”这时候再上矩阵快速幂。这种“由简入繁”的讲述方式为什么有效因为它展示了你的算法知识是有层次的你不仅知道“最优解长什么样”还能解释每一层优化解决了什么问题。这是面试官区分“会背题”和“真正理解”的最重要信号。加上你在实际写代码时可以顺势纠正自己的小错误那种自然的“先犯错再修正”反而比一上来就完美更真实。3.3 当面试官追问“还能更快吗”如何推导矩阵快速幂到了这一步不是每个候选人都扛得住。矩阵快速幂不仅要会写代码还要能讲清楚数学原理。如果面试官追问建议按以下顺序展开第一步先说“斐波那契数列可以写成矩阵形式”把那个2x2矩阵M [[1,1],[1,0]]写出来。这一步是核心因为你要让面试官看到你知道“递推关系可以被编码成矩阵乘法的形态”。第二步点明“求第n项等价于求M的n-1次方再乘以初始向量”。这里要说清楚指数为什么是n-1而不是n取决于初始向量的定义方式。比如用F(1)和F(0)作为初始向量则F(n)对应M^(n-1)。第三步讲快速幂的原理“求M^n可以用二分法把指数拆成二进制每轮迭代把矩阵自乘一次指数右移一位如果当前位为1就把结果矩阵乘上当前矩阵。这样总共只需要log n次矩阵乘法。”第四步写代码。代码不用太复杂2x2矩阵乘法单独写一个函数会让代码清晰很多也方便你讲清楚每一步。我遇到过一种情况候选人思路清晰但代码里写错了矩阵乘法顺序。result matrix_mul(result, mat)和result matrix_mul(mat, result)在很多情况下结果不一样因为矩阵乘法不满足交换律。快速幂里因为result初始为单位矩阵且乘法结合顺序其实在某些代码结构下不敏感但你要是自己写了一个不标准的顺序而不自知面试官追问起来会很尴尬。保险起见推荐严格遵守“结果的更新放在左边、底数矩阵的平方放在右边”的标准写法。3.4 压力测试大数取模与Python的任意精度陷阱面试现场最后一个高频追问是“如果n是10^18怎么处理”。这个问题的正确回答包含两步一要用矩阵快速幂保证O(log n)时间二要在每步矩阵乘法后立刻取模防止中间结果爆炸。Python里一个大坑是这个语言的整数是任意精度的。也就是说你算个数字本身多大的数都不会溢出但这恰恰是陷阱——不会溢出意味着中间结果可以无限增长你的算法可能因为不停计算超大整数的乘法而越来越慢。如果你不取模n10^18的矩阵快速幂在Python里会跑到天荒地老。所以即使Python不会溢出依然要显式取模。取模怎么取注意矩阵乘法里每个元素是两个乘积之和所以MOD 1000000007 def matrix_mul_mod(a, b): return [ [ (a[0][0] * b[0][0] a[0][1] * b[1][0]) % MOD, (a[0][0] * b[0][1] a[0][1] * b[1][1]) % MOD ], [ (a[1][0] * b[0][0] a[1][1] * b[1][0]) % MOD, (a[1][0] * b[0][1] a[1][1] * b[1][1]) % MOD ] ]记得每步都取模不要等到最后再取。取模运算有个性质(a b) % MOD ((a % MOD) (b % MOD)) % MOD乘法和加法都可以提前消掉模数保证中间结果始终在可控范围内。这个细节也是我在实际笔试里见过最多人踩坑的地方。再补充一个Python特有的优化点快速幂里用位运算power 1判断奇偶性、用power 1代替整除2虽然对幂运算提升幅度在大数场景下有限但写出来更能体现你对运行细节的掌握也给面试官留下好印象。4. 斐波那契数列的延伸与变体从一道题学会一类题4.1 爬楼梯问题同一个状态转移方程换了个马甲面试最怕的是变体。斐波那契数列有个非常经典的变体那就是爬楼梯问题一个人爬楼梯每次可以走1级或2级台阶问爬到第n级台阶有多少种不同的走法。这个问题咋一看跟斐波那契毫无关系但仔细想要走到第n级台阶最后一步只可能来自第n-1级迈1级或者第n-2级迈2级。所以总走法数f(n) f(n-1) f(n-2)边界条件是f(1)1, f(2)2。这个递推式跟斐波那契数列一模一样只是初始值不同。我在面试中见过一个候选人把斐波那契代码默写出来然后套到爬楼梯上结果边界条件写错了——他把F(0)0, F(1)1直接搬过来导致正确答案差了1。这个案例告诉我们理解初始条件和索引对齐是变体题最核心的考点。你不仅要知道“递推式子一样”还要知道“初始条件可能不同”。4.2 更多的变体跳台阶、铺砖、蜜蜂路径一旦你看穿了“马甲”的本质这类题就能举一反三。跳台阶变体每次可以跳1级、2级或3级台阶那么递推式变成f(n) f(n-1) f(n-2) f(n-3)初始条件也要相应调整。这个变体考验你能不能从“最后一次跳了几级”这个视角重新建模。铺砖问题用1x2的砖铺2xN的地板求铺法总数。把砖横着铺和竖着铺分类讨论你会发现也是斐波那契结构。蜜蜂路径问题蜜蜂只能从编号小的蜂房爬向编号相邻的大蜂房求从a到b的路径数。因为每一步只能前进1或2格本质上又回到斐波那契。这些题目的共同点是它们都满足“无后效性”和“最优子结构”——当前状态只依赖前序固定个数的状态。面试官出这些变体考察的其实就是你有没有真正理解状态转移方程的本质能不能把斐波那契数列识别成为“线性递推”这一大类问题的一个样例。4.3 递归爆栈的经典场景为什么Python里递归有1000层限制很多读者可能之前就知道Python有递归深度限制但不太清楚为什么是1000而不是更大的数字。Python解释器为了防止无限递归把C语言调用栈完全耗尽那会导致程序直接崩溃而不是抛出异常在Python层设置了一个安全阀值默认约1000层。这个限制在斐波那契问题上有什么影响你写一个递归斐波那契n500时就很可能触发RecursionError。很多初学者第一次见这个报错会觉得莫名其妙——明明逻辑没问题为什么跑不了这就是斐波那契数列对“刚入门Python又想准备算法面试”的同学设置的第一道坎你得从一开始就明白递归在Python里有天然的深度边界算法选型时必须考虑这一点。解决办法无非两个一个是改成迭代另一个是使用sys.setrecursionlimit显式调高限制但它本质上只是延后了问题无法彻底解决因为你把限制调得太高可能导致Python解释器自身崩溃。我个人的建议是算法面试中能用迭代写就用迭代写。这不光是为了规避Python的递归限制更是因为迭代版本通常更节省空间、更可控代码写起来也更不容易踩坑。4.4 矩阵快速幂的真正用武之地不只是斐波那契是所有线性递推矩阵快速幂能解决的问题远不止斐波那契。任何形如f(n) a1f(n-1) a2f(n-2) ... ak*f(n-k)的k阶线性递推关系都可以改写成k x k矩阵乘法的形式然后用快速幂在O(k^3 log n)时间内求出第n项。比如Tribonacci数列前三项之和你就能构造一个3x3矩阵[F(n) ] [1 1 1] [F(n-1)] [F(n-1)] [1 0 0] * [F(n-2)] [F(n-2)] [0 1 0] [F(n-3)]这个推广能力在面试里是巨大的加分项。当面试官问完斐波那契顺势问你“如果递推式改成三项之和呢”你能现场推导出对应的矩阵结构那就说明你不是背了一个函数而是理解了整类问题的本质。我建议每个人把“从递推式写转移矩阵”这个技能练熟第一行放各系数的组合其余行做单位位移。这个技能在中学竞赛和面试里都是硬通货一旦掌握可以举一反三。写多了你会发现矩阵快速幂的面试题翻来覆去都是在同一套框架上做文章。4.5 我在实际代码评审中见过的那些斐波那契“翻车”现场聊到最后分享几个我在实际代码评审和面试辅导中反复见到的错误。这些坑对大多数认真准备过的人来说可能“低级”但在紧张环境下特别容易犯。第一个坑递归版里忘记处理n1的边界。如果n0或n1没有直接返回代码会无限递归下去最后报错。很多人写递归只顾着递推式一落笔就把边界丢了。第二个坑在迭代DP里从i0开始循环一不小心就访问了负索引。Python里dp[-1]不会像C那样直接段错误而是悄悄返回列表最后一个元素这个行为在面试现场很容易导致你debug半天找不出问题。我在帮人改代码时看到过好几次写了个dp[i] dp[i-1] dp[i-2]但i从0开始循环结果dp[-1]和dp[-2]都是列表尾部元素答案彻底错误。第三个坑矩阵乘法中顺序写反。前面提过矩阵乘法不满足交换律A乘B和B乘A通常结果不同。快速幂的模板里如果result和mat的乘法顺序反过来在指数为奇数时就会出错。建议把matrix_mul(a, b)定义为返回a * b然后快速幂循环里统一写成result matrix_mul(result, mat)这样逻辑跟数学定义对齐不易乱。第四个坑用字典做记忆化但键的写法很糟糕。比如用字符串拼接的key “fib-n-3”这会让哈希运算变慢缓存命中率还低。正确做法是用列表或整数键Python的整数哈希是自身不存在转换开销性能好得多。第五个坑没考虑空间。n1000000时用数组存全部结果也是可以的但如果面试官问了“空间还能不能优化”你说不会那这道题的价值就打折了。滚动变量不是炫技是动态规划空间优化的标准姿势一定要练到闭着眼睛写得出来。5. 从这道题延伸出的面试策略别只刷题要刷“复杂度层级的直觉”我把这条单独放最后单独说因为它是我面试别人和被人面试之后沉淀下来的最重要体会。斐波那契数列这道题本质上是在训练一种算法敏感度看到一个计算题你能在几秒钟内判断出它的复杂度上界然后立刻想出对应层级的解法。这是一个“复杂度层级直觉”不是背题能背出来的必须靠大量反复推演建立。我建议读者做一个练习把斐波那契数列的四种解法朴素递归、记忆化递归、迭代DP、矩阵快速幂分别用Python实现然后对n从小到大跑一遍记录下耗时。比如n10、20、30、40、50迭代和递归的时间差距会非常直观地呈现出来。我自己当年就是用jupyter notebook跑的这张表看完之后对“算法复杂度决定一切”有了身体记忆。做完基础练习再尝试手动推一遍矩阵快速幂的数学推导不看任何参考资料从递推式出发写出矩阵形式再写快速幂代码最后验证结果。这个过程重复三遍基本上面试遇到怎么追问你都能接得住。这道题刷透之后你会发现自己的算法思维有个质变——因为你在一个看似最简单的题目上看到了从O(2^n)到O(log n)的完整演进路径。这种“复杂度层级感”才是面试官真正在找的东西也是你拿到offer之后做工程架构设计时真正需要用到的东西。斐波那契数列刷完接下来你可以主动挑战它的亲兄弟变体爬楼梯、铺砖、跳台阶、Tribonacci把这几个变体放在一起横向对比你会发现它们的状态转移方程都是一回事只不过在边界和台阶数量上做了文章。刷完这一组你对动态规划的入门就真正完成了。
返回列表