首页 > 代码库 > 求Fibonacci数的三种方法和时间复杂度解析
求Fibonacci数的三种方法和时间复杂度解析
题目:
定义Fibonacci数列如下:
f(0)=1
f(0)=1
f(1)=1
f(n)=f(n-1)+f(n-2), n>=2
f(n)=f(n-1)+f(n-2), n>=2
输入n,用最快的方法求该数列的第n项。
解答一:
直接用公式写递归函数。很简单,很低效,就不写了。时间复杂度T(N) = T(N-1) + T(N-2); 也是f(n)本身,2^(n/2)<f(n)<2^n。
解答二:
用循环求,也很直接,效率很高了,时间复杂度是O(n)。
int f(int n)
{
if(n <= 1)
return 1;
int f0=1, f1=1;
for(int i=2; i<=n; ++i)
{
int t=f0+f1;
f0=f1;
f1=t;
}
return f1;
}
解答三:
用矩阵求,时间复杂度O(log n),效率是最高的。
Fibonacci数列递推公式可以使用矩阵表达:
[f(n),f(n+1)]=[f(n-1),f(n)] * =[f(0),f(1)] *=[1,1]*, n>=0
用G(n)表达该矩阵的n次方,规定G(0)为单位阵I。
那么
G(2n)=G(n)*G(n)
G(2n+1)=G(n)*G(n)*G(1)
写出递归函数【伪代码】,时间复杂度O(log n):
Matrix2x2 g(int n)
{
if(n<=0) return G(0);
if(n==1) return G(1);
Matrix2x2 t = f(n/2); return t*t*G(n%2);
}
矩阵运算还是比较麻烦,比较耗时的,仔细研究G(n)的结构,容易发现G(n)可以表示为如下形式:
这可以很容易地用数学归纳法证明。就不赘述了。
也就是说可以用两个整数(x,y)来表示G(n)。
f(n)=[1 1]*=x+y
这样可以重新实现该递归函数【C++代码】:
void g(int n, int& x, int& y)
{
if(n<=1)
{
x = 0;
y = 1;
}
else
{
int x1, y1;
g(n/2, x1, y1);
x = x1*x1+y1*y1;
y = (2*x1+y1)*y1;
if(n % 2)
{
int t = x;
x = y;
y += t;
}
}
}
int f2(int n)
{
int x, y;
g(n, x, y);
return x+y;
}
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。