Computational Complexity of 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 / 斐波那契数列的时空复杂度的更多相关文章
- ***1133. Fibonacci Sequence(斐波那契数列,二分,数论)
1133. Fibonacci Sequence Time limit: 1.0 secondMemory limit: 64 MB is an infinite sequence of intege ...
- 10、end关键字和Fibonacci series: 斐波纳契数列
# Fibonacci series: 斐波纳契数列 # 两个元素的总和确定了下一个数 a, b = 0, 1 #复合赋值表达式,a,b同时赋值0和1 while b < 10: print(b ...
- [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 ...
- Fibonacci series(斐波纳契数列)的几种常见实现方式
费波那契数列的定义: 费波那契数列(意大利语:Successione di Fibonacci),又译费波拿契数.斐波那契数列.斐波那契数列.黄金切割数列. 在数学上,费波那契数列是以递归的方法来定义 ...
- 【算法】Fibonacci(斐波那契数列)相关问题
一.列出Fibonacci数列的前N个数 using System; using System.Collections.Generic; using System.Linq; using System ...
- 509. Fibonacci Number斐波那契数列
网址:https://leetcode.com/problems/fibonacci-number/ 原始的斐波那契数列 运用自底向上的动态规划最佳! 可以定义vector数组,但是占用较多内存空间 ...
- POJ 3070 Fibonacci【斐波那契数列/矩阵快速幂】
Fibonacci Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 17171 Accepted: 11999 Descr ...
- 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).. ...
- 【LeetCode每天一题】Fibonacci Number(斐波那契数列)
The Fibonacci numbers, commonly denoted F(n) form a sequence, called the Fibonacci sequence, such th ...
随机推荐
- JavaScript HTML DOM 关系层级(父子兄弟姐妹关系)
通过 HTML DOM,您能够使用节点关系来导航节点树. DOM 节点 根据 W3C HTML DOM 标准,HTML 文档中的所有事物都是节点: 整个文档是文档节点 每个 HTML 元素是元素节点 ...
- OpenCV之Core组件进阶
颜色空间缩减 利用C++类型转换时向下取整操作,实现定义域内颜色缩减.表达式如下 Inew = (Iold/10)*10 简单的颜色空间缩减算法可由以下两步组成: (1)遍历图像矩阵的每个元素 (2) ...
- CAN总线电平(隐性与显性)
CAN2.0B规范定义了两种互补的逻辑数值:显性和隐性.同时传送显性和隐性位时,总线呈现显性状态:同时传送显性状态位时,总线呈现显性状态:同时传送隐性状态位时,总线呈现隐性状态.显性数 ...
- c++中sort函数调用报错Expression : invalid operator <的内部原理 及解决办法
转自:https://www.cnblogs.com/huoyao/p/4248925.html 当我们调用sort函数进行排序时,中的比较函数如果写成如下 bool cmp(const int &a ...
- Linux - Shell - find - 基础
概述 find 基础 背景 查找文件 人的记忆能力, 是有限的 计算机里的文件数量, 虽然不是无限, 但是也不少 要去找那些 记不清楚的文件, 必然要用查找 准备 OS centos7 用户 root ...
- Docker - 查看容器进程在宿主机的 PID
概述 查看 docker 进程, 在容器外的 pid 背景 docker 中运行的进程, 本质上是运行在 host 上的 这些进程, 在 host 上, 也可以有自己的 pid 如果某种情况下, 连不 ...
- 2019牛客多校第四场A meeting 思维
meeting 题意 一个树上有若干点上有人,找出一个集合点,使得所有人都到达这个点的时间最短(无碰撞) 思路 就是找树的直径,找直径的时候记得要找有人的点 #include<bits/stdc ...
- Iris_xorm
xorm表基本操作及高级操作 表结构基本操作 对表结构的操作最常见的操作是查询和统计相关的方法,我们首先来看相关实现: 条件查询 Id值查询:参数接收主键字段的值.例如: var user User ...
- Call to undefined function Illuminate\Encryption\openssl_cipher_iv_length()
今天遇到一个错误,没有定义一个openssl_cipher_iv_length()方法,可是我明明开启OpenSSL了啊 如果开启了还报错 只需要把php的目录加入环境变量 -重启电脑 就解决了 但 ...
- codeforces Make The Fence Great Again(dp)
题目链接:http://codeforces.com/contest/1221/problem/D 题目要求ai ! = ai-1,草纸上推理一下可以发现每一个栅栏可以升高的高度无非就是 +0,+1, ...