《剑指Offer》—— 第10题:斐波那契数列

斐波那契数列与剪绳子

题目来源于《剑指Offer》的第10,14题,都可以用动态规划的思路来解决问题。

斐波那契数列

斐波那契数列是数学中非常有名的数列,在中国也可以叫杨辉三角。其递推公式简单明了:
f ( n ) = f ( n − 1 ) + f ( n − 2 ) ( n > 1 且 n ∈ N + ) f(n) = f(n-1) + f(n-2) (n>1且 n\in N^+) f(n)=f(n1)+f(n2)(n>1nN+)
f ( n ) = { 0 n = 0 1 n = 1 f ( n − 1 ) + f ( n − 2 ) n > 1 且 n ∈ N + f(n)= \left\{ \begin{array}{lcl} 0 & & n=0\\ 1 & & n=1\\ f(n-1) + f(n-2) & & n>1且n\in N^+ \end{array} \right. f(n)=01f(n1)+f(n2)n=0n=1n>1nN+
对于求解f(n)这个问题的求解就可以从两个方向着手,

  • 第一是自顶而下递归的方法;

  • 第二是自底向上的方法。

所谓自顶而下的方法即是当我们要求解 f ( n ) f(n) f(n)的时候,先去求解 f ( n − 1 ) f(n-1) f(n1) f ( n − 2 ) f(n-2) fn2,当遇到已知的 f ( 1 ) f(1) f(1) f ( 0 ) f(0) f(0)时,递归终止。写成代码可以为

int FibSeq(int n){
	if(n==0){
		return 0;
	}
	if(n==1){
		return 1;
	}
	return FibSeq(n-1) + FibSeq(n-2);
}

代码十分简略,分析其时空复杂度,时间上由于计算每一个f(n)都要分解为两个f(n-1)和f(n-2),时间复杂度为 O ( 2 n ) O(2^n) O(2n)。每次递归都需要系统在堆栈分配一个空间,所以他的空间复杂度也为 O ( 2 n ) O(2^n) O(2n)

通过以上的分析可以看出,这种递归方法的效率不能接受。但为什么会这么多呢?图片来自
通过qiuxiaonao画出的用户迭代图可以看出,f(1)和f(2)等被多次计算,且回顾转移方程,我们只需要保存最近的两个结果f(n-1)和f(n-2)即可计算出f(n)。

int FibSeq(int n){
	if(n==0){
		return 0;
	}
	if(n==1){
		return 1;
	}
	int preRes[2] = {0,1};
	int prePoint = 0;
	int res = 0;
	for(int i=2;i<=n;i++){
		res = preRes[0] + preRes[1];
		preRes[prePoint] = res;
		prePoint =  1 - prePoint;
	}
	return res;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值