Fibonacci Sequence 维基百科

\(F(n) = F(n-1)+F(n-2)\),其中 \(F(0)=0, F(1)=1\),即该数列由 0 和 1 开始,之后的数字由相邻的前两项相加而得出。

递归

def fibonacci(n):
    assert n >= 0, 'invalid n'
    if n < 2: return n
    return fibonacci(n - 1) + fibonacci(n -2)

递归方法的时间复杂度为高度为 \(n-1\) 的不完全二叉树的节点数,所以近似为 \(O(2^n)\)

数学求解方法:

\(T(n) = T(n-1) + T(n-2) \qquad (n>1)\)

设 \(f(n)\) 为参数为 n 时的时间复杂度 \(f(n) = f(n-1) + f(n-2)\)

转化为求二阶常系数齐次差分方程,设通解为 \(f_{n} = C_{1}f_{n-1} + C_{2}f_{n-2}\)

设有特解 \(f_{n} = \lambda\),\(\lambda\) 为非零待定常数,将 \(\lambda\) 代入方程,易得特征方程 \(\lambda ^{2} = \lambda + 1\),则 \(λ = \frac{1\pm \sqrt{5}}{2}\)

再根据 \(f(0) = 0, f(1) = 1.\) 求出 \(C_{1}\) 和 \(C_{2}\)

得出通项公式

\[
f(n) = \frac{1}{\sqrt{5}}[(\frac{1+ \sqrt{5}}{2})^{n} - (\frac{1- \sqrt{5}}{2})^{n}]
\]

当 \(n->\infty\) 时, \(\left |(\frac{1- \sqrt{5}}{2})^{n} \right |<1\),所以趋于零。

时间复杂度为 \(O((\frac{1+ \sqrt{5}}{2})^{n})\) ,约等于 \(O(1.618^{n})\) ,即指数级复杂度 \(O(2^n)\),递归算法空间复杂度取决于递归的深度,显然为 \(O(n)\)。

迭代

def fibonacci(n):
    assert n >= 0, 'invalid n'
    if n == 0: return 0
    a, b = 0, 1
    for _ in range(n - 1):
        a, b = b, a+b
    return b

时间复杂度 \(O(n)\),空间复杂度 \(O(1)\)

矩阵

\(F(n)\) 和 \(F(n - 1)\) 写成一个 2 x 1 的矩阵,然后对其进行变形。

\(\begin{bmatrix}F_{n}\\F_{n-1}\end{bmatrix}=\begin{bmatrix}F_{n-1}+F_{n-2}\\F_{n-1}\end{bmatrix}=\begin{bmatrix}1\times F_{n-1}+1\times F_{n-2}\\1\times F_{n-1}+0\times F_{n-2}\end{bmatrix}=\begin{bmatrix}1 & 1\\ 1 & 0\end{bmatrix}\times\begin{bmatrix}F_{n-1}\\F_{n-2}\end{bmatrix}=...=\begin{bmatrix}1&1\\1&0\end{bmatrix}^{n-1}\times\begin{bmatrix}F_{1}\\F_{0}\end{bmatrix}=\begin{bmatrix}1&1\\1&0\end{bmatrix}^{n-1}\times\begin{bmatrix}1\\0\end{bmatrix}\)

因此要求 \(F_{n}\),只要对这个二阶方阵求 \(n - 1\) 次方,最后取结果方阵第一行第一列的数字就可以了。

等式中的矩阵 \(\begin{bmatrix}1&1\\1&0\end{bmatrix}\) 被称为斐波那契数列的 Q- 矩阵。

通过 Q- 矩阵,我们可以利用如下公式进行计算:

\(F_{n} = Q^{n-1}_{1,1}\)

如此一来,计算斐波那契数列的问题就转化为了求 \(Q^{n-1}\) 的问题。

\[
A^{n} = \begin{cases} A\cdot (A^{2})^{\frac{n-1}{2}}, & \text{if $n$ is odd} \\\ (A^{2})^{\frac{n}{2}}, & \text{if $n$ is even} \\ \end{cases}
\]

可见时间复杂度满足 \(T(n) = T(n / 2) + O(1)\)
Master 定理 可得

时间复杂度 \(O( \log n)\) ,空间复杂度显然为 \(O(1)\)

from numpy import matrix

def MatrixPower(mat, n):
    assert n > 0, 'invalid n'
    res = None
    temp = mat
    while True:
      if n & 1:
        if res is None: res = temp
        else: res = res * temp
      n >>= 1
      if n == 0: break
      temp = temp * temp
    return res

def fibonacci(n):
    assert n >= 0, 'invalid n'
    if n < 2: return n  # F(0) = 0, F(1) = 1
    mat = matrix([[1, 1], [1, 0]], dtype=object)
    mat = MatrixPower(mat, n - 1)
    return mat[0, 0]

通项公式法

def fibonacci(n):
    root_Five = 5**0.5
    result = (((1 + root_Five) / 2)**n - ((1 - root_Five) / 2)**n) / root_Five
    return int(result)

显然,该方法的时空复杂度均为 \(O(1)\) , 但使用公式计算的方法由于有大量的浮点运算,在 n 增大时浮点误差不断增大会导致返回结果不正确甚至数据溢出。

方法 时间复杂度 空间复杂度
递归 \(O(2^{n})\) \(O(n)\)
迭代 \(O(n)\) \(O(1)\)
矩阵 \(O(log^{n})\) \(O(1)\)
公式 \(O(1)\) \(O(1)\)

Computational Complexity of Fibonacci Sequence / 斐波那契数列的时空复杂度的更多相关文章

  1. ***1133. Fibonacci Sequence(斐波那契数列,二分,数论)

    1133. Fibonacci Sequence Time limit: 1.0 secondMemory limit: 64 MB is an infinite sequence of intege ...

  2. 10、end关键字和Fibonacci series: 斐波纳契数列

    # Fibonacci series: 斐波纳契数列 # 两个元素的总和确定了下一个数 a, b = 0, 1 #复合赋值表达式,a,b同时赋值0和1 while b < 10: print(b ...

  3. [Amazon] Program for Fibonacci numbers 斐波那契数列

    The Fibonacci numbers are the numbers in the following integer sequence. 0, 1, 1, 2, 3, 5, 8, 13, 21 ...

  4. Fibonacci series(斐波纳契数列)的几种常见实现方式

    费波那契数列的定义: 费波那契数列(意大利语:Successione di Fibonacci),又译费波拿契数.斐波那契数列.斐波那契数列.黄金切割数列. 在数学上,费波那契数列是以递归的方法来定义 ...

  5. 【算法】Fibonacci(斐波那契数列)相关问题

    一.列出Fibonacci数列的前N个数 using System; using System.Collections.Generic; using System.Linq; using System ...

  6. 509. Fibonacci Number斐波那契数列

    网址:https://leetcode.com/problems/fibonacci-number/ 原始的斐波那契数列 运用自底向上的动态规划最佳! 可以定义vector数组,但是占用较多内存空间 ...

  7. POJ 3070 Fibonacci【斐波那契数列/矩阵快速幂】

    Fibonacci Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 17171   Accepted: 11999 Descr ...

  8. Fibonacci(斐波那契数列)的第N位数

    无穷数列1,1,2,3,5,8,13,21,34,55...称为Fibonacci数列,它可以递归地定义为F(n)=1 ...........(n=1或n=2)F(n)=F(n-1)+F(n-2).. ...

  9. 【LeetCode每天一题】Fibonacci Number(斐波那契数列)

    The Fibonacci numbers, commonly denoted F(n) form a sequence, called the Fibonacci sequence, such th ...

随机推荐

  1. Apache-Tomcat-Ajp漏洞(CVE-2020-1938)漏洞复现(含有poc)

    Apache-Tomcat-Ajp漏洞(CVE-2020-1938)漏洞复现 0X00漏洞简介 Apache与Tomcat都是Apache开源组织开发的用于处理HTTP服务的项目,两者都是免费的,都可 ...

  2. No Delegate set : lost message:libpng error: Not a PNG file

    当出现这个问题时,是因为本来是jpg或其他格式的图片存成了png导致的.或者有的图片本来就是jpg的,Android Studio一编译,发现不是png才造成了这个问题.解决这个问题可以在Androi ...

  3. 使用vue实现复选框单选多选

    界面样式: <div class="right_con" v-if="isClickApply" style="border:none" ...

  4. django初步了解(一)

    安装django pip3 install django==版本号 创建一个djangp项目 django-admin startproject 项目名 目录介绍: 运行django项目: pytho ...

  5. hdu2328 后缀树

    #include <cstdio> #include <cstdlib> #include <cstring> #include <cmath> #in ...

  6. 洛谷 P1659 [国家集训队]拉拉队排练(Manacher)

    题目链接:https://www.luogu.com.cn/problem/P1659 思路: 首先跑一遍Manacher,用$cnt_i$记录长为$i$的回文串有多少个. 所记录的$cnt$并不是最 ...

  7. 【vue store的使用方法】(this.$store.state this.$store.getters this.$store.dispatch this.$store.commit)

    vue 页面文件 <template> <div> {{this.$store.state.count}}<br/> {{count}}<br/> {{ ...

  8. 编程道拓扑bcd.top 0x01/ 开局第一篇: 随便聊聊/ 随笔

    0x01 开局 编程道拓扑(bcd.top)是一个前端从业者的思考和总结, 如果你喜欢, 欢迎关注! 作者是一个前端从业者, 本系列会总结作者在工作和学习中的一些思考, 会有具体的技术点, 也会有关于 ...

  9. JSP技术(三)

    JSP指令 指令是JSP语法元素的第一种类型.它们指示JSP转换器如何翻译JSP页面为Servlet.JSP定义了多个指令,但只有page和include最重要.而taglib.tag.attribu ...

  10. go key-value缓存go-cache实现

    Cache类型 Cache封装了一个cache类型,cache类型的参数解析: 1.defaultExpiration time.Duration 每个键值的默认过期时间. 2.items map[s ...