考研中递推函数求法的几种代码实现(以斐波那契数列为例)

概念

斐波那契数列(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(n1)+F(n2),n2,nN

代码实现

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)
代码略

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值