如何使用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将html转成PDF的实现代码(包含中文)
Mar 04 Python
python sort、sorted高级排序技巧
Nov 21 Python
解密Python中的描述符(descriptor)
Jun 03 Python
python脚本内运行linux命令的方法
Jul 02 Python
用Python解决计数原理问题的方法
Aug 04 Python
Python实现的递归神经网络简单示例
Aug 11 Python
PyQt5主窗口动态加载Widget实例代码
Feb 07 Python
python实现梯度下降算法
Mar 24 Python
Python动态语言与鸭子类型详解
Jul 01 Python
Pandas分组与排序的实现
Jul 23 Python
Python3的socket使用方法详解
Feb 18 Python
Docker如何部署Python项目的实现详解
Oct 26 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版(2)
2006/10/09 PHP
php对象和数组相互转换的方法
2015/05/12 PHP
php结合curl实现多线程抓取
2015/07/09 PHP
ThinkPHP防止重复提交表单的方法实例分析
2018/05/10 PHP
php数组指针函数功能及用法示例
2020/02/11 PHP
Jquery同辈元素选中/未选中效果的实例代码
2013/08/01 Javascript
JS获取当前日期和时间的简单实例
2013/11/19 Javascript
jQuery实现的超简单点赞效果实例分析
2015/12/31 Javascript
KnockoutJS 3.X API 第四章之表单textInput、hasFocus、checked绑定
2016/10/11 Javascript
浅析如何利用angular结合translate为项目实现国际化
2016/12/08 Javascript
vue.js单页面应用实例的简单实现
2017/04/10 Javascript
js获取css的各种样式并且设置他们的方法
2017/08/22 Javascript
js判断文件类型大小并给出提示的实现方法
2018/01/03 Javascript
Bootstrap开发中Tab标签页切换图表显示问题的解决方法
2018/07/13 Javascript
JS原生瀑布流效果实现
2019/04/26 Javascript
实例详解vue中的$root和$parent
2019/04/29 Javascript
基于vue、react实现倒计时效果
2019/08/26 Javascript
layer.open回调获取弹出层参数的实现方法
2019/09/10 Javascript
JS实现横向轮播图(中级版)
2020/01/18 Javascript
vue-cli点击实现全屏功能
2020/03/07 Javascript
JS实现iframe中子父页面跨域通讯的方法分析
2020/03/10 Javascript
ES5和ES6中类的区别总结
2020/12/21 Javascript
python根据出生年份简单计算生肖的方法
2015/03/27 Python
详解Python list 与 NumPy.ndarry 切片之间的对比
2017/07/24 Python
Pandas把dataframe或series转换成list的方法
2020/06/14 Python
python爬取音频下载的示例代码
2020/10/19 Python
利用python+request通过接口实现人员通行记录上传功能
2021/01/13 Python
美国床垫和床上用品公司:Nest Bedding
2017/06/12 全球购物
西班牙美妆电商:Perfume’s Club(有中文站)
2018/08/08 全球购物
linux面试题参考答案(6)
2016/06/23 面试题
简述进程的启动、终止的方式以及如何进行进程的查看
2013/07/12 面试题
幼儿园新年寄语
2014/04/03 职场文书
教师群众路线学习心得体会
2014/11/04 职场文书
初中生思想道德自我评价
2015/03/09 职场文书
500字作文之关于爸爸
2019/11/14 职场文书
MySQL慢查询优化解决问题
2022/03/17 MySQL