输出fibonacci数列的第n项的各种算法分析
二分递归
cpp
#include <iostream>
using namespace std;
long long fib ( int n ) { //计算Fibonacci数列的第n项(二分递归版):O(ϕ^n)
return ( 2 > n ) ?
(long long) n //若到达递归基,直接取值
: fib ( n - 1 ) + fib ( n - 2 ); //否则,递归计算前两项,其和即为正解
}
int main() {
int n = 32; //n不能太大,否则运行时间会很长
cout << fib(n);
return 0;
}
对应的邓公PPT,其中 ϕ = 5 + 1 2 \phi =\frac{\sqrt{5}+1}{2} ϕ=25 +1
记忆化搜索
cpp
#include <iostream>
using namespace std;
long long M[90] {0};//n=93时,fibonacci(n)就会导致64位带符号整数溢出.
long long fibonacci(int n){
if(n < 2){//此时直接return了,可以认为是一种"懒惰抄袭"
cout << "懒惰抄袭:调用fibonacci" << "(" << n << ")" << endl;
return n;
}
else if(M[n]== 0){
M[n] = fibonacci(n-1)+ fibonacci(n-2);
cout << "实际计算:";
}
else{
cout << "懒惰抄袭:";
}
cout << "调用fibonacci" << "(" << n << ")" << endl;
return M[n];
}
int main() {
int n = 6;
cout << fibonacci(n);
return 0;
}
代码运行结果:
对应的邓公PPT:
显然时间复杂度是 O ( n ) O(n) O(n).
动态规划
cpp
#include <iostream>
using namespace std;
long long fibI ( int n ) { //计算Fibonacci数列的第n项(迭代版):O(n)
long long f = 1, g = 0; //初始化:fib(-1)、fib(0)
while ( 0 < n-- ) { g += f; f = g - f; } //依据原始定义,通过n次加法和减法计算fib(n)
return g; //返回
}
int main() {
int n = 6;
cout << fibI(n);
return 0;
}
显然时间复杂度是 O ( n ) O(n) O(n).
借助快速幂
cpp
#include <iostream>
using namespace std;
//矩阵结构
struct Matrix {
long long a, b, c, d;
Matrix(long long a, long long b, long long c, long long d) : a(a), b(b), c(c), d(d) {}
};
//矩阵乘法
Matrix multiply(const Matrix& m1, const Matrix& m2) {
return Matrix(m1.a * m2.a + m1.b * m2.c, m1.a * m2.b + m1.b * m2.d,
m1.c * m2.a + m1.d * m2.c, m1.c * m2.b + m1.d * m2.d);
}
//矩阵的快速幂算法
Matrix matrixPower(const Matrix& base, int n) {
if (n == 0) return Matrix(1, 0, 0, 1); // 单位矩阵
Matrix half = matrixPower(base, n >> 1);
Matrix result = multiply(half, half);
if (n & 1) result = multiply(result, base);
return result;
}
long long fibonacci(int n){
Matrix base(0, 1, 1, 1);
return matrixPower(base, n).b;
}
int main() {
int n = 64;
cout << fibonacci(64);
return 0;
}
由于矩阵的快速幂算法复杂度是 O ( log n ) O(\log n) O(logn),故此算法时间复杂度为 O ( log n ) O(\log n) O(logn)