博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
算法题003 斐波那契(Fibonacci)数列
阅读量:4677 次
发布时间:2019-06-09

本文共 1997 字,大约阅读时间需要 6 分钟。

 

斐波那契(Fibonacci)数列

题目来源

  斐波那契(Fibonacci)数列是经典的递推关系式定义的数列。

  第一项是0,第二项是1,之后的每一项都是前面两项之和。

  

  POJ3070:

  九度剑指Offer:

 

递归的方法:低效

  用递归的方法解斐波那契数列的第n项的值是很直观的做法,因为斐波那契数列的定义就是这种递推的形式。

 

//用递归的方法求解Fibonacci数列int Fibonacci(int n){    if(n <= 0)    {        return 0;    }    else if (n == 1)    {        return 1;    }    else    {        return Fibonacci(n - 1) + Fibonacci(n - 2);    }}

 

 

 

  但是,递归的方法不是一种很好的解法,有很严重的效率问题

  比如,计算F[5],需要计算F[4]和F[3],而计算F[4]的时候又要计算F[3],所以存在很多结点的重复计算。

  像是一颗二叉树,父结点为左右结点之和,那么为了求根节点上的F[n],就要求它的左右结点F[n-1]和 F[n-2],而这两个结点的求法和根节点相同,这样扩展下去,当n较大时,计算量会急剧增大。

 

递推关系式的优化:保存数列中间项,避免重复计算

  为了减少重复的计算,可以用一个数组储存所有已计算过的项

  这样便可以达到用空间换取时间的目的。

  在这种情况下,时间复杂度为O(n),而空间复杂度也为O(n)。

  

  这样做的好处在需要多次计算f(n)时更加有利

  比如已经计算过了f(100),那么就表明f(100)之前的结果都已经计算出来并保存了,第二次想要计算f(50)时,直接查询即可得到。

  代码如下,在九度上提交AC()。

  

#include "stdafx.h"#include 
using namespace std;int Fibonacci(int n);int main(int argc, char* argv[]){ int n = 0; long fibonacci[1000]; int count = 0;//保存数列已经计算了多少 //先设定起始条件 fibonacci[0] = 0; fibonacci[1] = 1; count = 1; while(cin>>n) { //递归算法 //cout << Fibonacci(n) << endl; //非递归算法 //因为要多次计算f(n),所以保存这个数列可进一步提高效率 if(n > count) { for(int i = count + 1; i <= n; ++i) { fibonacci[i] = fibonacci[i-1] + fibonacci[i-2]; } cout << fibonacci[n] << endl; } else { //如果n小于等于count,则表明f(n)已经计算出来并且存储在相应的位置上了 cout << fibonacci[n] << endl; } } return 0;}//用递归的方法求解Fibonacci数列int Fibonacci(int n){ if(n <= 0) { return 0; } else if (n == 1) { return 1; } else { return Fibonacci(n - 1) + Fibonacci(n - 2); }}

 

 

 

  需要注意的是,开始的时候我用的是int类型数组,所以总是无法通过,因为测试用例的数字已经超过了整形的表示范围。

 

其他优化方法

  《编程之美》中还提到了其他优化方法:

  求解通项公式;

  使用分治策略,求解矩阵的方幂。

 

参考资料

  《剑指Offer》

  《编程之美》

  Online Judge:

  POJ3070:

  九度剑指Offer:

  相关解答博客:

 

 

转载于:https://www.cnblogs.com/mengdd/archive/2013/03/11/2953315.html

你可能感兴趣的文章
C#特征备忘
查看>>
intelil——快捷键
查看>>
Java 面向对象 之 final 关键字
查看>>
Contact Form 7邮件发送失败的解决办法
查看>>
How to use For loop in CruiseControl.net
查看>>
P1800 software_NOI导刊2010提高(06)
查看>>
Python学习日记(1)使用if __name__ == "main"
查看>>
二进制的最大公约数
查看>>
Mybatis学习笔记(一) 之框架原理
查看>>
ABSTRACT的方法是否可同时是STATIC,是否可同时是NATIVE,是否可同时是SYNCHRONIZED?
查看>>
【SPL标准库专题(10)】SPL Exceptions
查看>>
《Python从入门基础到实践》
查看>>
【读入优化】
查看>>
python-网络编程urllib模块
查看>>
0029 Java学习笔记-面向对象-枚举类
查看>>
CGRectGet *** 获取控件坐标的方法
查看>>
SQL的主键和外键约束
查看>>
Bookmarklet
查看>>
c++primer 第l六章编程练习答案
查看>>
上海秋季HCC小记
查看>>