如何使用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编程中装饰器的使用示例解析
Jun 20 Python
Python切换pip安装源的方法详解
Nov 18 Python
python多进程和多线程究竟谁更快(详解)
May 29 Python
python 常见字符串与函数的用法详解
Nov 23 Python
Python3爬楼梯算法示例
Mar 04 Python
Python分布式进程中你会遇到的问题解析
May 28 Python
python pandas模块基础学习详解
Jul 03 Python
python3.x提取中文的正则表达式示例代码
Jul 23 Python
python list转置和前后反转的例子
Aug 26 Python
matplotlib对象拾取事件处理的实现
Jan 14 Python
python解决12306登录验证码的实现
Apr 18 Python
Python基于Tkinter开发一个爬取B站直播弹幕的工具
May 06 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中截取中文字符串的代码小结
2011/07/17 PHP
php中一个有意思的日期逻辑处理
2012/03/25 PHP
php中防止恶意刷新页面的代码小结
2012/10/31 PHP
php获取网页中图片、DIV内容的简单方法
2014/06/19 PHP
PHP学习笔记(一):基本语法之标记、空白、和注释
2015/04/17 PHP
举例讲解PHP面对对象编程的多态
2015/08/12 PHP
php similar_text()函数的定义和用法
2016/05/12 PHP
php/JS实现的生成随机密码(验证码)功能示例
2019/06/06 PHP
基于Laravel 5.2 regex验证的正确写法
2019/09/29 PHP
jquery 打开窗口返回值实现代码
2010/03/04 Javascript
JQuery 插件模板 制作jquery插件的朋友可以参考下
2010/03/17 Javascript
Jquery ui css framework
2010/06/28 Javascript
jQuery实现的感应鼠标悬停图片色彩渐显效果
2015/03/03 Javascript
jquery左右全屏大尺寸多图滑动效果代码分享
2015/08/28 Javascript
JavaScript中的对象继承关系
2016/08/01 Javascript
Vue+axios 实现http拦截及路由拦截实例
2017/04/25 Javascript
BootStrap下的弹出框加载select2框架失败的解决方法
2017/08/31 Javascript
Node.js如何使用Diffie-Hellman密钥交换算法详解
2017/09/05 Javascript
jQuery UI 实例讲解 - 日期选择器(Datepicker)
2017/09/18 jQuery
react的hooks的用法详解
2020/10/12 Javascript
Python中的迭代器漫谈
2015/02/03 Python
在pycharm 中添加运行参数的操作方法
2019/01/19 Python
简单了解python中的f.b.u.r函数
2019/11/02 Python
python3 实现调用串口功能
2019/12/26 Python
python 基于selenium实现鼠标拖拽功能
2020/12/24 Python
一套SQL笔试题
2016/08/14 面试题
企业员工培训感言
2014/02/26 职场文书
2015迎新晚会开场白
2015/05/29 职场文书
高效笔记技巧分享:学会这些让你不再困扰
2019/09/04 职场文书
Python中requests做接口测试的方法
2021/05/30 Python
详细介绍python类及类的用法
2021/05/31 Python
Vue过滤器(filter)实现及应用场景详解
2021/06/15 Vue.js
SpringBoot实现quartz定时任务可视化管理功能
2021/08/30 Java/Android
JS创建或填充任意长度数组的小技巧汇总
2021/10/24 Javascript
JavaScript阻止事件冒泡的方法
2021/12/06 Javascript
python获取字符串中的email
2022/03/31 Python