如何使用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通过cookie模拟已登录状态的初步研究
Nov 09 Python
Python机器学习k-近邻算法(K Nearest Neighbor)实例详解
Jun 25 Python
使用python语言,比较两个字符串是否相同的实例
Jun 29 Python
Python爬虫基础之XPath语法与lxml库的用法详解
Sep 13 Python
基于Python实现定时自动给微信好友发送天气预报
Oct 25 Python
python 获取一个值在某个区间的指定倍数的值方法
Nov 12 Python
Python设计模式之代理模式实例详解
Jan 19 Python
用Python获取摄像头并实时控制人脸的实现示例
Jul 11 Python
python创建与遍历List二维列表的方法
Aug 16 Python
python科学计算之numpy——ufunc函数用法
Nov 25 Python
Jupyter notebook如何实现指定浏览器打开
May 13 Python
教你怎么用Python操作MySql数据库
May 31 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+XML 制作简单的留言本 图文教程
2009/11/02 PHP
php防止SQL注入详解及防范
2013/11/12 PHP
在Mac OS上搭建Nginx+PHP+MySQL开发环境的教程
2015/12/21 PHP
PHP微信开发之根据用户回复关键词\位置返回附近信息
2016/06/24 PHP
Laravel 验证码认证学习记录小结
2019/12/20 PHP
JavaScript监测ActiveX控件是否已经安装过的代码
2008/09/02 Javascript
自己的js工具 Event封装
2009/08/21 Javascript
JavaScript去掉数组中的重复元素
2011/01/13 Javascript
js添加table的行和列 具体实现方法
2013/07/22 Javascript
JS中判断null、undefined与NaN的方法
2014/03/24 Javascript
window.print打印指定div指定网页指定区域的方法
2014/08/04 Javascript
基于vuejs+webpack的日期选择插件
2020/05/21 Javascript
NodeJS实现客户端js加密
2017/01/09 NodeJs
详解js中Array的方法及技巧
2018/09/12 Javascript
mpvue性能优化实战技巧(小结)
2019/04/17 Javascript
vue flex 布局实现div均分自动换行的示例代码
2020/08/05 Javascript
在vue中使用cookie记住用户上次选择的实例(本次例子中为下拉框)
2020/09/11 Javascript
[48:12]Secret vs Optic Supermajor 胜者组 BO3 第三场 6.4
2018/06/05 DOTA
复制粘贴功能的Python程序
2008/04/04 Python
Python代码的打包与发布详解
2014/07/30 Python
浅谈SciPy中的optimize.minimize实现受限优化问题
2020/02/29 Python
Python 实现 T00ls 自动签到脚本代码(邮件+钉钉通知)
2020/07/06 Python
python wsgiref源码解析
2021/02/06 Python
scrapy-splash简单使用详解
2021/02/21 Python
爱尔兰电子产品购物网站:Komplett.ie
2018/04/04 全球购物
24岁生日感言
2014/01/13 职场文书
简历上的自我评价
2014/02/03 职场文书
《自然之道》教学反思
2014/02/11 职场文书
弘扬职业精神演讲稿
2014/03/20 职场文书
荷叶母亲教学反思
2014/04/30 职场文书
关于晚自习早退的检讨书
2014/09/13 职场文书
2015年员工试用期工作总结
2014/12/12 职场文书
项目建议书
2015/02/04 职场文书
MySQL中IF()、IFNULL()、NULLIF()、ISNULL()函数的使用详解
2021/06/26 MySQL
36个正则表达式(开发效率提高80%)
2021/11/17 Javascript
ipad隐藏软件app图标方法
2022/04/19 数码科技