如何使用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中函数的用法实例教程
Sep 08 Python
Python学习之asyncore模块用法实例教程
Sep 29 Python
Python实现更改图片尺寸大小的方法(基于Pillow包)
Sep 19 Python
pycharm远程linux开发和调试代码的方法
Jul 17 Python
关于python列表增加元素的三种操作方法
Aug 22 Python
python实现根据指定字符截取对应的行的内容方法
Oct 23 Python
matplotlib命令与格式之tick坐标轴日期格式(设置日期主副刻度)
Aug 06 Python
pytorch 实现在一个优化器中设置多个网络参数的例子
Feb 20 Python
PyCharm设置注释字体颜色以及是否倾斜的操作
Sep 16 Python
linux centos 7.x 安装 python3.x 替换 python2.x的过程解析
Dec 14 Python
python 实现图与图之间的间距调整subplots_adjust
May 21 Python
使用Django实现商城验证码模块的方法
Jun 01 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+AJAX实现无刷新注册(带用户名实时检测)
2007/01/02 PHP
wordpress之wp-settings.php
2007/08/17 PHP
用PHP ob_start()控制浏览器cache、生成html实现代码
2010/02/16 PHP
Apache服务器无法使用的解决方法
2013/05/08 PHP
基于php socket(fsockopen)的应用实例分析
2013/06/02 PHP
php获取网页上所有链接的方法
2015/04/03 PHP
基于CI(CodeIgniter)框架实现购物车功能的方法
2018/04/09 PHP
PHP实现十进制数字与二十六进制字母串相互转换操作示例
2018/08/10 PHP
一个不错的应用,用于提交获取文章内容,不推荐用
2007/03/03 Javascript
基于jQuery UI CSS Framework开发Widget的经验
2010/08/21 Javascript
在多个页面使用同一个HTML片段《续》
2011/03/04 Javascript
Javascript基础回顾之(一) 类型
2017/01/31 Javascript
Webpack+Vue如何导入Jquery和Jquery的第三方插件
2017/02/20 Javascript
Vue keep-alive实践总结(推荐)
2017/08/31 Javascript
vue router使用query和params传参的使用和区别
2017/11/13 Javascript
webpack自动打包和热更新的实现方法
2019/06/24 Javascript
详解element-ui中el-select的默认选择项问题
2019/08/02 Javascript
js 动态校验开始结束时间的实现代码
2020/05/25 Javascript
[02:36]DOTA2混沌骑士 英雄基础教程
2013/11/26 DOTA
[52:03]DOTA2-DPC中国联赛 正赛 Ehome vs iG BO3 第三场 1月31日
2021/03/11 DOTA
python self,cls,decorator的理解
2009/07/13 Python
Python的Django框架中的select_related函数对QuerySet 查询的优化
2015/04/01 Python
Python实现PS滤镜中马赛克效果示例
2018/01/20 Python
对python requests发送json格式数据的实例详解
2018/12/19 Python
python 实现读取一个excel多个sheet表并合并的方法
2019/02/12 Python
Python使用百度api做人脸对比的方法
2019/08/28 Python
用python介绍4种常用的单链表翻转的方法小结
2020/02/24 Python
python json 递归打印所有json子节点信息的例子
2020/02/27 Python
html5 音乐播放器 audio 标签使用概述
2013/07/15 HTML / CSS
飞利浦法国官网:Philips法国
2019/07/10 全球购物
饮料业务员岗位职责
2013/12/15 职场文书
雪山饭庄的创业计划书范文
2014/01/18 职场文书
美德好少年事迹材料
2014/01/19 职场文书
中国世界遗产导游词
2015/02/13 职场文书
mybatis 获取无数据的字段不显示的问题
2021/07/15 Java/Android