概念
斐波那契数列(Fibonacci sequence),又称黄金分割数列,因数学家莱昂纳多·斐波那契(Leonardoda Fibonacci)以兔子繁殖为例子而引入,故又称为“兔子数列”,指的是这样一个数列:0、1、1、2、3、5、8、13、21、34、……在数学上,斐波那契数列以如下被以递推的方法定义: F ( n ) = { 0 , n = 0 1 , n = 1 F ( n − 1 ) + F ( n − 2 ) , n ≥ 2 , n ∈ N ∗ F(n)=\left\{\begin{array}{c} 0, n=0 \\ 1, n=1 \\ F(n-1)+F(n-2), n \geq 2, n \in \mathrm{N}^{*} \end{array}\right. F(n)=⎩⎨⎧0,n=01,n=1F(n−1)+F(n−2),n≥2,n∈N∗
代码实现
for循环实现
int Fibonacci(int n){
int fv0=0,fv1=1;
if(n==0) return fv0;
for(int i=1;i<n;i++){
int temp=fv0+fv1;
fv0=fv1;
fv1=temp;
}
return fv1;
}
时间复杂度: O ( n ) O(n) O(n)
递归实现
int Fibonacci(int n){
if(n==0) return 0;
if(n==1) return 1;
return Fibonacci(n-1)+Fibonacci(n-2);
}
时间复杂度: O ( 2 n ) O(2^n) O(2n)
递归实现(记忆化搜索)
int _Fibonacci(int n,int *a){
if(n==0) return 0;
if(n==1) return 1;
if(a[n]!=-1) return a[n];//已经计算过
return a[n]=_Fibonacci(n-1,a)+_Fibonacci(n-2,a);
}
int Fibonacci(int n){
int *a=(int*)malloc(sizeof(int)*(n+1));//辅助数组
memset(a,-1,sizeof(int)*(n+1));//-1表示还没计算过
int ans=_Fibonacci(n,a);
free(a);
return ans;
}
时间复杂度: O ( n ) O(n) O(n)
用栈模拟递归
int Fibonacci(int n){
struct stack{
int num;//下标
int val;// 值
};
stack *st=(stack*)malloc(sizeof(stack)*(n+1));
int top=-1;
int fv0=0,fv1=1;
if(n==0) return fv0;
for(int i=n;i>1;i--)
st[++top].num=i;//入栈
while(top>-1){
st[top].val=fv0+fv1;
fv0=fv1;
fv1=st[top].val;
top--;//出栈
}
return fv1;
free(st);
}
时间复杂度: O ( n ) O(n) O(n)
矩阵快速幂(算法竞赛内容,略)
[
f
(
0
)
f
(
1
)
]
[
0
1
1
1
]
=
[
f
(
1
)
f
(
0
)
+
f
(
1
)
]
=
[
f
(
1
)
f
(
2
)
]
[f(0) \quad f(1)]\left[\begin{array}{ll} 0 & 1 \\ 1 & 1 \end{array}\right]=[f(1) \quad f(0)+f(1)]=[f(1) \quad f(2)]
[f(0)f(1)][0111]=[f(1)f(0)+f(1)]=[f(1)f(2)]
递推可得
[
f
(
0
)
f
(
1
)
]
[
0
1
1
1
]
n
=
[
f
(
n
)
f
(
n
+
1
)
]
[f(0) \quad f(1)]\left[\begin{array}{ll} 0 & 1 \\ 1 & 1 \end{array}\right]^{n}=[f(n) \quad f(n+1)]
[f(0)f(1)][0111]n=[f(n)f(n+1)]
[
0
1
1
1
]
n
\left[\begin{array}{ll}0 & 1 \\ 1 & 1\end{array}\right]^{n}
[0111]n使用矩阵快速幂计算时间复杂度只有
O
(
l
o
g
n
)
O(logn)
O(logn),所以总的时间复杂度为
O
(
l
o
g
n
)
O(logn)
O(logn)
代码略