如何使用Python实现斐波那契数列


Posted in Python onJuly 02, 2019

斐波那契数列(Fibonacci)最早由印度数学家Gopala提出,而第一个真正研究斐波那契数列的是意大利数学家 Leonardo Fibonacci,斐波那契数列的定义很简单,用数学函数可表示为:

如何使用Python实现斐波那契数列

数列从0和1开始,之后的数由前两个数相加而得出,例如斐波那契数列的前10个数是:0, 1, 1, 2, 3, 5, 8, 13, 21, 34。

用 Python 实现斐波那契数列常见的写法有三种,各算法的执行效率也有很大差别,在面试中也会偶尔会被问到,通常面试的时候不是让你简单的用递归写写就完了,还会问你时间复杂度怎样,空间复杂度怎样,有没有可改进的地方。

递归法

所谓递归就是指函数的定义中使用了函数自身的方法

def fib_recur(n):
assert n >= 0
if n in (0, 1):
return n
return fib_recur(n - 1) + fib_recur(n - 2)
for i in range(20):
print(fib_recur(i), end=" ")
>>> 0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584 4181

递归是一种代码最简洁的方法,但它是效率非常低,因为会出现大量的重复计算,时间复杂度是:O(1.618 ^ n),1.618是黄金分割。同时受限于 Python 中递归的最大深度是 1000,所以用递归来求解并不是一种可取的办法。

递推法

递推法就是从0和1开始,前两项相加逐个求出第3、第4个数,直到求出第n个数的值

def fib_loop(n):
a, b = 0, 1
for i in range(n):
a, b = b, a + b
return a
for i in range(20):
print(fib_loop(i), end=" ")
>>> 0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584 4181

这种算法的时间复杂是O(n),呈线性增长,如果数据量巨大,速度越到后面会越慢。

上面两种方式都是使用分而治之的思想,就是把一个大的问题化小,然后利用小问题的求解得到目标问题的答案。

矩阵法

《线性代数》是大学计算机专业低年级的课程,这门课教的就是矩阵,那时候觉得这东西学起来很枯燥,没什么用处,工作后你才发现搞机器学习、数据分析、数据建模时大有用处,书到用时方恨少。其实矩阵的本质就是线性方程式。

斐波那契数列中两个相邻的项分别为:F(n) 和 F(n - 1),如果把这两个数当作一个2行1列的矩阵可表示为:

如何使用Python实现斐波那契数列

因为 F(n) = F(n-1)+F(n-2),所以就有:

如何使用Python实现斐波那契数列

通过反推,其实它是两个矩阵的乘积得来的

如何使用Python实现斐波那契数列

依此类推:

如何使用Python实现斐波那契数列

最后可推出:

如何使用Python实现斐波那契数列

因此想要求出F(n)的值,只要能求出右边矩阵的n-1次方的值,最后求得两矩阵乘积,取新矩阵的第一行的第一列的值即可,比如n=3时,

如何使用Python实现斐波那契数列

​可以得知F(3)的值2,F(2)的值为1,因为幂运算可以使用二分加速,所以矩阵法的时间复杂度为 O(log n)

我们可以用科学计算包 numpy 来实现矩阵法:

import numpy
def fib_matr(n):
return (numpy.matrix([[1, 1], [1, 0]]) ** (n - 1) * numpy.matrix([[1], [0]]))[0, 0]
for i in range(20):
print(int(fib_matr(i)), end=" ")
>>> 0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584 4181

3中不同的算法效率对比:

如何使用Python实现斐波那契数列

从上面图可以看出递归法效率惊人的低,矩阵法在数据量比较大的时候才突显出它的优势,递推法随着数据的变大,所花的时间也越来越大。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
21行Python代码实现拼写检查器
Jan 25 Python
Python 统计字数的思路详解
May 08 Python
pandas 小数位数 精度的处理方法
Jun 09 Python
Django保护敏感信息的方法示例
May 09 Python
python将字符串list写入excel和txt的实例
Jul 20 Python
使用APScheduler3.0.1 实现定时任务的方法
Jul 22 Python
Python的互斥锁与信号量详解
Sep 12 Python
Python3 shutil(高级文件操作模块)实例用法总结
Feb 19 Python
Python 解析简单的XML数据
Jul 24 Python
python re.match()用法相关示例
Jan 27 Python
Python图像处理之膨胀与腐蚀的操作
Feb 07 Python
解决python绘图使用subplots出现标题重叠的问题
Apr 30 Python
pandas数据筛选和csv操作的实现方法
Jul 02 #Python
Python列表与元组的异同详解
Jul 02 #Python
Pandas中resample方法详解
Jul 02 #Python
Python何时应该使用Lambda函数
Jul 02 #Python
Python Pandas分组聚合的实现方法
Jul 02 #Python
使用Python做垃圾分类的原理及实例代码附源码
Jul 02 #Python
python flask框架实现重定向功能示例
Jul 02 #Python
You might like
复杂检索数据并分页显示的处理方法
2006/10/09 PHP
php时间戳转换的示例
2014/03/31 PHP
ThinkPHP表单自动提交验证实例教程
2014/07/18 PHP
php操作redis缓存方法分享
2015/06/03 PHP
JQuery制作的放大效果的popup对话框(未添加任何jquery plugin)分享
2013/04/28 Javascript
在Iframe中获取父窗口中表单的值(示例代码)
2013/11/22 Javascript
js中的时间转换—毫秒转换成日期时间的示例代码
2014/01/26 Javascript
javascript制作sql转换为stringBuffer的小工具
2015/04/03 Javascript
微信小程序 template模板详解及实例代码
2017/03/09 Javascript
Angular.JS利用ng-disabled属性和ng-model实现禁用button效果
2017/04/05 Javascript
Django+Vue.js搭建前后端分离项目的示例
2017/08/07 Javascript
Swiper自定义分页器使用详解
2017/12/28 Javascript
p5.js入门教程和基本形状绘制
2018/03/15 Javascript
jQuery事件多次绑定与解绑问题实例分析
2019/02/19 jQuery
javascript中call,apply,callee,caller用法实例分析
2019/07/24 Javascript
微信小程序实现单个卡片左滑显示按钮并防止上下滑动干扰功能
2019/12/06 Javascript
python中使用xlrd、xlwt操作excel表格详解
2015/01/29 Python
Python实现html转换为pdf报告(生成pdf报告)功能示例
2019/05/04 Python
python与字符编码问题
2019/05/24 Python
基于sklearn实现Bagging算法(python)
2019/07/11 Python
python的time模块和datetime模块实例解析
2019/11/29 Python
详解Python3.8+PyQt5+pyqt5-tools+Pycharm配置详细教程
2020/11/02 Python
CSS3实现超慢速移动动画效果非常流畅无卡顿
2014/06/15 HTML / CSS
css3 中的新特性加强记忆详解
2016/04/16 HTML / CSS
英国派对礼服和连衣裙购物网站:TFNC London
2018/07/07 全球购物
Mankind美国/加拿大:英国领先的男士美容护发用品公司
2018/12/05 全球购物
师范生实习的个人自我鉴定
2013/10/20 职场文书
竞选大学学委演讲稿
2014/09/13 职场文书
2014年工程工作总结
2014/11/25 职场文书
2014年小学辅导员工作总结
2014/12/23 职场文书
客服专员岗位职责范本
2015/04/07 职场文书
宾馆安全管理制度
2015/08/06 职场文书
会计入职心得体会
2016/01/22 职场文书
《这片土地是神圣的》教学反思
2016/02/16 职场文书
一文彻底理解js原生语法prototype,__proto__和constructor
2021/10/24 Javascript
NGINX 权限控制文件预览和下载的实现原理
2022/01/18 Servers