递归因o(2ⁿ)时间复杂度和栈溢出问题不适用于实际计算;迭代安全通用,仅需滚动更新前两项;矩阵快速幂仅适用于n达10⁹级且模数固定场景。

递归实现最直观但完全不能用于实际计算,迭代是日常首选,矩阵快速幂只在超大 n(比如 10⁹ 级别)且模数固定时才值得上;三者不是平替关系,而是适用场景截然不同。
为什么递归版本 fib(n) 在 n > 40 就明显卡顿
它的时间复杂度是 O(2ⁿ),因为每层调用都分裂成两个子调用,大量重复计算(如 fib(3) 在算 fib(5) 和 fib(4) 时各算一次)。没有缓存的纯递归连 fib(50) 都可能跑几十秒。
如果你只是想验证逻辑或教学演示,可以加个 std::map 记忆化,但那已不属于“朴素递归”——而一旦加了记忆化,它就退化为时空换时间的 DP,和迭代写法本质一致。
- 不要在生产代码里写裸递归求斐波那契
- 编译器无法自动优化这种指数级分支,
-O2也救不了 - 栈深度随
n线性增长,n ≈ 10⁵就大概率触发栈溢出
迭代写法怎么写才安全又通用
核心是只保留前两项,滚动更新。注意三个关键点:初始状态、循环边界、整数溢出控制。
long long fib_iter(int n) {
if (n
- 用
long long而非int,否则fib(47)就溢出 -
n = 0和n = 1必须特判,否则循环不执行,返回值错乱 - 如果需求是取模(比如
fib(n) % 1000000007),每次加法后立刻取模,避免中间值溢出
矩阵快速幂适合什么场景,以及容易漏掉的初始化细节
它把递推转为矩阵幂:[f(n), f(n-1)]^T = [[1,1],[1,0]]^(n-1) * [f(1),f(0)]^T,用快速幂将时间压到 O(log n)。但它只在 n 极大(≥ 10⁶)且必须单次查询时才有意义——预处理不如迭代,多组查询不如打表。
常见坑:
- 单位矩阵写错:2×2 单位阵是
{{1,0},{0,1}},不是全 1 或对角线为 0 - 幂次搞混:算
fib(n)应该乘[[1,1],[1,0]]^(n-1),不是n次;n=0和n=1仍需单独返回 - 矩阵乘法顺序不能反:左乘基矩阵,即
res = res * base,不是base * res - 若需取模,所有加法和乘法中间步骤都要
% MOD,否则long long也会爆
真正要用矩阵快速幂时,往往意味着问题已脱离“算一个斐波那契数”的范畴,比如在线查询、带修改的线段树维护、或与线性递推式耦合。单纯为了“快”而硬套,反而让代码更难懂、更难测。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











