三种方法求解Fibonacci(斐波那契)数列
三种方法求解Fibonacci(斐波那契)数列
(一)
所谓Fibonacci数列是指这样一种数列,它的前两项均为1,从第三项开始各项均为前两项之和。用数学公式表示出来就是:
1 (n=1,2)
fib(n)=
fib(n-1)+fib(n-2) (n>2)
可以证明斐波那契数列的通项公式为fib(n) = [(1+√5)/2]^n /√5 - [(1-√5)/2]^n /√5 (n=1,2,3.....),关于斐波那契数列的详细介绍请参阅百度百科。
下面我将介绍三种比较常用的求解第n项斐波那契数列的方法:递归法、迭代法、通项公式法。
1、递归法
这种方法的优点是简洁和容易理解,缺点是时间复杂度太大,随着n的增大,运算时间将会急剧增加。因此在很多场合这种方法是不可取的。
使用这种方法的关键代码是:
if(n == 1|| n== 2)
{
return 1;
}
else
{
return fib(n - 1) + fib(n - 2);
}
2、表驱动的递归法
这里不提纯粹的表驱动法,因为对于项数未知的Fibonacci数列开启大片的空间来换取时间未免不值得且不负责。我们只是为了消除递归法中大量重复的运算,可以将已经计算过的中间值存入一个表,已备后续使用:
#define MAX_LOG 20
static unsigned long Logs[MAX_LOG] = {0};
unsigned long Fib(int n)
{
if (n <= 1) {
return n;
} else if (n < MAX_LOG && Logs[n] != 0) {
return Logs[n];
} else {
Logs[n] = Fib(n - 1) + Fib(n - 2);
return Logs[n];
}
}
(二)
当n小于保存的表长时,由于每个中间值只计算一次,时间复杂度降为O(n)。但随着n的增大,要想维持O(n)的时间复杂度,就必须扩大保存的表长,这就造成了存储空间的浪费。
3、迭代法
这种方法相对于递归法来说在时间复杂度上减小了不少,但代码相对就要复杂些了。它的思想是这样的,假设开始时f0=1,f1=1,currentFib表示当前斐波那契数,则:
for(i = 1;i < n;i++)
{
currentFib = f0 + f1;
f0 = f1;
f1 = currentFib;
}
这样迭代结束和currentFib就是fib(n)了。
4、转移矩阵法。此方法通常见于线性代数中的Markov过程示例。Fibonacci数列第n项与第n-1项可以通过转移矩阵的n-1次迭代求出:
function y = Fib(n)
first = [1; 0];
trans = [1 1; 1 0];
last = trans ^ (n - 1) * first;
y = last(1, 1);
end
此算法的时间复杂度相当于计算矩阵乘方的时间复杂度。在计算2阶矩阵n次方时,如果直接按矩阵乘法定义式展开,不加特别优化,其时间复杂度为O(n)。
5、通项公式法
这种方法是最没技术含量的方法,只要你知道通项公式照着把它翻译成编程语言就可以了,优点不言而喻。function y = Fib(n)
sr5 = sqrt(5);
y = uint32((((1 + sr5) / 2) ^ n - ((1 - sr5) / 2) ^ n) / sr5);
end
该方法的时间复杂度貌似为O(1),但我们还应该考虑乘方运算的时间消耗。不加特别优化时,用乘法实现n次乘方的时间复杂度为O(n)。考虑到浮点数计算效率和精度问题,此方法在计算机实现时不如转移矩阵法。
三种方法求解Fibonacci(斐波那契)数列相关推荐
- 三种方法详解斐波那契数列
本文同步.md文件,在展示上会有些许问题 原始版本在语雀平台.请各位移步查阅. 代码保存在码云平台供有需要者下载阅览. 本文采用暴力递归,带备忘录的递归,以及动态规划求解斐波那契数列.不到之处,欢迎指 ...
- python编写递归函数、求斐波那契数列第n项_Python非递归算法求解Fibonacci斐波那契数列...
斐波那契数列递归数学定义如下:F0=0,F1=1,Fn=F(n-1)+F(n-2)(n>=2,n∈N*) Python代码: 函数f(n),输入非负整数n,返回f[n] def f(n): a, ...
- 【C语言编程】求Fibonacci(斐波那契)数列前40个数
问题: 求Fibonacci(斐波那契)数列前40个数. 分析: 这个数列有如下特点:第1,2两个数为1,1.从第三个数开始,该数是其前面两个数之和.即该数列为1,1,2,3,5,8,13,- ,用数 ...
- 用php递归求fibonacci数列,C++_C语言求Fibonacci斐波那契数列通项问题的解法总结,一:递归实现使用 - phpStudy...
C语言求Fibonacci斐波那契数列通项问题的解法总结 一:递归实现 使用公式f[n]=f[n-1]+f[n-2],依次递归计算,递归结束条件是f[1]=1,f[2]=1. 二:数组实现 空间复 ...
- 求Fibonacci(斐波那契)数列的的前n项
1.Fibonacci(斐波那契)数列的定义规律:第一项a1=0,第二项a2=1,从第三项起,每一项都等于前面两项之和. 2.使用a1,a2,a3进行迭代 代码 #include using name ...
- C++fibonacci斐波那契数列,自下而上(附完整源码)
C++fibonacci斐波那契数列,自下而上 fibonacci斐波那契数列,自下而上算法的完整源码(定义,实现,main函数测试) fibonacci斐波那契数列,自下而上算法的完整源码(定义,实 ...
- C++ 求Fibonacci(斐波那契数列)前n项的和
1.题目:求Fibonacci(斐波那契数列)前n项的和,n<=20 Fibonacci数: 1 1 2 3 5 8 13 21 34 - 思路:先求出前20项的数,分别存到数组中.需要时,直接 ...
- 用程序猿思维、程序设计师思维两种方式写求斐波那契数列的方法。
//用Java实现斐波那契数列(Fibonacci) public class Test {public int f(int n)//n代表第几个数字.程序返回它相应的值{return n>2? ...
- 斐波纳契数列 java_几种复杂度的斐波那契数列的Java实现
一:斐波那契数列问题的起源 13世纪初期,意大利数论家Leonardo Fibonacci在他的著作Liber Abaci中提出了兔子的繁殖问题: 如果一开始有一对刚出生的兔子,兔子的长大需要一个月, ...
- 斐波那契数列python循环算法求解_斐波那契数列的算法实现 —— python
斐波那契数列,简单地说,起始两项为0和1,此后的项分别为它的前两项之后. (注:据我百度发现,斐波那契数列的定义并非起始的两项为0和1,而是1和1,鉴于是转发的,在这里不对原作者的文章进行改动,因为, ...
最新文章
- Spring 中的各种注解,光会用可不够哦!
- java怎么判断字符串是否为空的几种方法(亲测)
- oracle运维工作中每天巡检的必要性--job的相关问题
- 无盘服务器集群,镜像(无盘柜)-单活集群解决方案
- Java中volatile的作用以及用法
- Matlab批量读取csv、txt、prn等文件
- Java垃圾回收(GC)机制
- flash 模拟eeprom
- halo输入QQ号获取QQ头像和名称
- UML图:用例图详细介绍
- 边做边学入门微信小程序之仿豆瓣评分
- ASP.NET 有哪些web服务器-
- MS Office 开发工具--VBA
- oppo系统更新服务器,系统升级,这些OPPO用户有福了!
- 老友记全10集看完了,2个月的时光一晃而过!
- VVIC接口,item_get - 根据ID取商品详情
- 是一个新的开始,还是冥冥之中已经在路上。
- 百度编辑器(ueditor)魔改:3、高亮提示、搜索(广告词、违禁词等)
- 计算机显示无法打开打印机,添加打印机时电脑弹出错误窗口“Windows无法打开添加打印机”(适用 Windows OS)...
- [数论]-----中国剩余定理(扩展中国剩余定理)
热门文章
- 解决Ubuntu 22.04 LTS作为nfs server时根文件系统挂载失败的问题
- 史上最“犯贱”的十首情歌
- 18岁少年盗取1500万日元萌乃币, 逼交易所关停, 引发日本史上第一次加密币盗窃法律诉讼...
- 聊一个自己写的MVC框架
- 调用百度API(七)——获取百度API token 通用代码
- 关于JFrame添加背景图片,setbounds的小知识
- 扑克牌练习 【数据结构】
- 初学莫队算法 bzoj2038 小z的袜子 分块算法
- 程序员必备的 58 个学习网站
- 移动端图形架构之PowerVR of Imagination Tile-based rendering