动态规划学习之三种方法解决斐波拉契数

斐波拉契数是一个很经典的问题,也会很多公司面试的考题,每个学习计算机的同学都会接触这个问题,尤其是在学习递归的时候,利用递归来解决斐波拉契数是很多教材采用的一个例子,所以很多同学一想到斐波拉契马上就会采用递归,递归貌似简单,但是效率真的很高吗?不然!下面是我在学习动态规划的过程中总结的集中解决斐波拉契数的不同方法:

一、最野蛮最原始的方法

long f0(int n) { if (n == 0 || n == 1) return n; else return F(n - 1) + F(n - 2); }
这是最直接的递归方式,其时间复杂度为O(1.618^n),是一个指数时间级的算法,当n超过30时,你就慢慢等待吧,运气差的话直接死机了。


二、自底向上的动态规划方法

我们已知F(0)和F(1)的值,则我们从F(2)开始就可以利用前面两个已经计算出来的值,这样从小到大就可以最终求出F(n)

long F(int n) { long f1,f2,k,t; if(n < 2) return n; f1 = f2 = 1; for (k = 2; k < n; k++) { t = f1 + f2; f1 = f2; f2 = t; } return t; }
其时间复杂度已经从指数级降到线性级O(n)了,空间复杂度为O(1)


三、自顶向下的动态规划方法

这种方法也是采用递归的思想,但是确应用了动态规划的原理:将以前的计算结果存储起来备用,这样在以后出现同样的问题时就不用重复计算。也叫备忘录方法。

int fib[1000] = {0}; long f1(int n) { int t; if(fib[n] != 0) return fib[n]; if(n == 0) t = 0; if(n == 1) t = 1; if(n > 1) t = f1(n-1) + f1(n - 2); return fib[n] = t; }
自顶向下的动态规划递归方法大大减少了递归调用的次数,避免了重复递归计算,其算法时间复杂度也为线性级,其关键就是能够"保存已经计算过的子问题的结果".

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值