Fibonaci数列,求f(n)?

Fibonaci数列,求f(n)?
在这里插入图片描述

# 方法一:
int fib(int n){
	// base case
	if(n==0||n==1) return n;
	return fib(n-1) + fib(n-2);
}
# 这种方法虽然简单,但是时间复杂度却为指数级的,而且存在很多重复子问题。
# 那么如何消除这种重复子问题呢?比如f(17)是计算了两次(如图1),很显然每次计算都要
# 该f(n)是否遍历过呢,定义一个备忘录数组memo[n+1],初始化为0.

# 方法二:
int fib(int n){
	// 备忘录全部初始化为0
	int[] memo = new int[n+1]; #这里由于fib(n)对应着 memo[n],数组从0开始,所以申请n+1个大小长度
	return helper(memo,n);
}
int helper(int[] memo,int n){
	// base case
	if(n==0||n==1) return n;
	if(memo[n]!=0) return memo[n];
	memo[n] = helper(memo,n-1) + helper(memo,n-2);
	return memo[n];
}
# 采用备忘录后直接就把树形结构的指数级时间复杂度,转化为链式的o(n)。如图2
# 是否还能继续优化呢?我们看到既然通过备忘录把二叉树拉成了链式结构,那么空间复杂度有必要用o(n+1)个吗?很显然从图2中看出,只需要存储前面的两个就能得到当前的元素。

# 方法三:
int fib(int n){
    // base case
	if(n==0||n==1) return n;
	int dp_i_1 = 1;
	int dp_i_2 = 0;
	for(int i = 2;i<=n;i++){
		int dp_i = dp_i_1 + dp_i_2 ;
		# 滚动交换
		dp_i_2 = dp_i_1 ;
		dp_i_1  = dp_i ;
}
	return dp_i_1  ;
	
}
	
	

在这里插入图片描述
图1
在这里插入图片描述
图2

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值