如何使用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 相关文章推荐
举例详解Python中的split()函数的使用方法
Apr 07 Python
基于python socketserver框架全面解析
Sep 21 Python
全面了解Nginx, WSGI, Flask之间的关系
Jan 09 Python
Python模块WSGI使用详解
Feb 02 Python
Django 视图层(view)的使用
Nov 09 Python
Opencv-Python图像透视变换cv2.warpPerspective的示例
Apr 11 Python
Django之使用内置函数和celery发邮件的方法示例
Sep 16 Python
Python使用QQ邮箱发送邮件报错smtplib.SMTPAuthenticationError
Dec 20 Python
Python标准库itertools的使用方法
Jan 17 Python
Python Unittest原理及基本使用方法
Nov 06 Python
Pycharm安装Qt Design快捷工具的详细教程
Nov 18 Python
Python爬虫实战之爬取京东商品数据并实实现数据可视化
Jun 07 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
PHP的FTP学习(二)
2006/10/09 PHP
用PHP和ACCESS写聊天室(四)
2006/10/09 PHP
数字转英文
2006/12/06 PHP
有关JSON以及JSON在PHP中的应用
2010/04/09 PHP
codeigniter教程之多文件上传使用示例
2014/02/11 PHP
ThinkPHP结合ajax、Mysql实现的客户端通信功能代码示例
2014/06/23 PHP
PHP实现二叉树的深度优先与广度优先遍历方法
2015/09/28 PHP
PHP多维数组排序array详解
2017/11/21 PHP
PHP结合Vue实现滚动底部加载效果
2017/12/17 PHP
js直接编辑当前cookie的脚本
2008/09/14 Javascript
JS window.opener返回父页面的应用
2009/10/24 Javascript
网易JS面试题与Javascript词法作用域说明
2010/11/09 Javascript
javascript判断机器是否联网的2种方法
2013/08/09 Javascript
页面加载完成后再执行JS的jquery写法以及区别说明
2014/02/22 Javascript
javascript数组操作方法小结和3个属性详细介绍
2014/07/05 Javascript
如何使用Bootstrap的modal组件自定义alert,confirm和modal对话框
2016/03/01 Javascript
深入理解jquery自定义动画animate()
2016/05/24 Javascript
AngularJS 表达式详细讲解及实例代码
2016/07/26 Javascript
Vue+element-ui 实现表格的分页功能示例
2018/08/18 Javascript
对VUE中的对象添加属性
2018/09/18 Javascript
JavaScript变量提升和严格模式实例分析
2019/01/27 Javascript
前端天气插件tpwidget使用方法详解
2019/06/24 Javascript
javascript设计模式 ? 解释器模式原理与用法实例分析
2020/04/17 Javascript
基于postman获取动态数据过程详解
2020/09/08 Javascript
[03:36]2015国际邀请赛第二日现场精彩集锦
2015/08/06 DOTA
python音频处理用到的操作的示例代码
2017/10/27 Python
关于Python字符编码与二进制不得不说的一些事
2020/10/04 Python
python如何利用Mitmproxy抓包
2020/10/10 Python
使用html5制作loading图的示例
2014/04/14 HTML / CSS
使用HTML和CSS实现的标签云效果(附demo)
2021/02/03 HTML / CSS
高一政治教学反思
2014/01/28 职场文书
学生不参加考试检讨书
2015/02/19 职场文书
运动会开幕式通讯稿
2015/07/18 职场文书
三十年再续同学情倡议书
2019/11/27 职场文书
Nginx+Tomcat实现负载均衡、动静分离的原理解析
2021/03/31 Servers
python OpenCV学习笔记
2021/03/31 Python