斐波那契数列学习
复习过程中涉及到计算算法的时间复杂度,课后例题中的“计算斐波那契数列时间复杂度”引起了自己的思考,通过学习,总结出好集中不同的方式。
斐波那契数列简介
斐波那契数列(意大利语:Successione di Fibonacci),又译为菲波拿契数列、菲波那西数列、斐波那契数列、黄金分割数列。
在数学上,费波那契数列是以递归的方法来定义:
- F[0] = 0
- F[1] = 0
- F[n] = F[n-1] + Fn-2
用文字来说,就是费波那契数列由0和1开始,之后的费波那契系数就是由之前的两数相加而得出。首几个费波那契系数是:
- 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233……
特别指出:0不是第一项,而是第零项。
计算方法
递归法
递归计算斐波那契数列的JavaScript如下:
1 | function Fibonacci1(n){ |
递归的方法很简单,但是显然十分显然存在大量的重复运算,效率低下很低,还会占用大量的内存。
- 时间复杂度:T(n) = O(2^n)
递推法
为了避免递归的低效率,我们可以采取累加的方式,一项一项的计算,JavaScript代码如下:
1 | function Fibonacci2(n){ |
- 时间复杂度:T(n) = O(n)
- 空间复杂度:O(n)
公式法
以下是斐波那契数列的常见递推公式:
$$ F_{n}=\dfrac {1}{\sqrt {5}}\times \left[ \left( \dfrac {1+\sqrt {5}}{2}\right) ^{n}-\left( \dfrac {1-\sqrt {5}}{2}\right) ^{n}\right] $$
公式法的JavaScript代码如下:
1 | function Fibonacci3(n){ |
虽然公式看起来不是很复杂,但是当中有很多的浮点运算,返回的结果也会因为n越来越大而不断产生更大的误差,因此并不可靠。
矩阵法
$$ \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} $$
由此可推得:
$$ \begin{bmatrix} F_{n} \ F_{n-1} \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} $$
那这里就把问题转换为了求矩阵的n-1次幂,利用快速幂的方式来计算:
$$ a_{n}=\begin{cases}a^{\dfrac {n}{2}}a^{\dfrac {n}{2}},ifniseven\ a^{\dfrac {n-1}{2}}a^{\dfrac {n-1}{2}}a,ifnisodd\end{cases} $$
以上方法的JavaScript代码如下:
1 | // 矩阵乘法 |
- 时间复杂度:T(n) = O(log(n))
今天的学习过程中并不是全部都理解透彻了,关于时间复杂度也还有更长的路去学习,本文仅关于一道课后题延伸出这些内容。
未完待续~~~