斐波那契数列
- 递归
- 非递归
斐波那契数列递推公式:
F(n)={1,x=01,x=1F(n−1)+F(n−2),x>=2
F(n)=\begin{cases}
1,\quad x=0 \\\\
1,\quad x=1 \\\\
F(n-1) + F(n-2) ,\quad x>=2
\end{cases}
F(n)=⎩⎪⎪⎪⎪⎪⎪⎨⎪⎪⎪⎪⎪⎪⎧1,x=01,x=1F(n−1)+F(n−2),x>=2
递归算法
long long Fib(int n) {
if (n == 0 || n == 1)
return 1;
return Fib(n - 1) + Fib(n - 2);
}
或者是
long long Fib(int n) {
return n <= 1 ? 1 : Fib(n - 1) + Fib(n - 2);
}
但是递归算法的时间效率非常低,时间复杂度为O(N^2)
因为在此过程中存在大量的重复计算:比如在求解Fib(6)时,需要求解Fib(5)和Fib(4),而在计算Fib(7)时,用到了Fib(6)和Fib(5),都会重复计算。
非递归算法
1.矩阵快速幂
矩阵快速幂就是将普通快速幂运算中的乘法运算换成了矩阵的乘法运算
const int N = 2;
int res[N][N];
void multi(long long a[][N], long long b[][N], int n) {
memset(res, 0, sizeof(res));
//矩阵乘法运算
for (int i = 0; i < N; i++)
for (int j = 0; j < N; j++)
for (int k = 0; k < N; k++)
res[i][j] += a[i][k] * b[k][j];
//将结果复制到a数组中,便于下一次循环的计算
for (int i = 0; i < N; i++)
for (int j = 0; j < N; j++)
a[i][j] = res[i][j];
}
long long ans[2][2];
//计算a的n次幂
long long Fib4(long long a[][N], int n) {
memset(ans, 0, sizeof(ans));
//初始化ans数组为1
for (int i = 0; i < N; i++)
ans[i][i] = 1;
//快速幂,只是将简单的乘法换成了矩阵的乘法运算
while (n) {
if (n & 1)
multi(ans, a, n);
multi(a, a, n);
n >>= 1;
}
return ans[0][1];
}
2.循环
利用数组实现
long long Fib(int n) {
int arr[maxn];
arr[0] = arr[1] = 1;
for (int i = 2; i < n; i++) {
arr[i] = arr[i - 1] + arr[i - 2];
}
return arr[n - 1];
}
3.公式
![F_{n} = \frac{1}{\sqrt{5} }[(\frac{1+\sqrt{5} }{2})^n - (\frac{1-\sqrt{5} }{2})^n]](https://i-blog.csdnimg.cn/blog_migrate/c015c1ce8115d7b3d8672a27a893d6ec.png)
时间复杂度O(1),但是涉及到浮点数,精度无法保证
代码略