python斐波那契数列的计算方法


Posted in Python onSeptember 27, 2018

题目:

计算斐波那契数列。具体什么是斐波那契数列,那就是0,1,1,2,3,5,8,13,21,34,55,89,144,233。

要求:

时间复杂度尽可能少

分析:

给出了三种方法:

方法1:递归的方法,在这里空间复杂度非常大。如果递归层数非常多的话,在python里需要调整解释器默认的递归深度。默认的递归深度是1000。我调整了半天代码也没有调整对,因为递归到1000已经让我的电脑的内存有些撑不住了。

方法2:将递归换成迭代,这样时间复杂度也在代码中标注出来了。

方法3:这种方法利用了求幂的简便性,采用了位运算。但是代价在于需要建立矩阵,进行矩阵运算。所以,当所求的数列的个数较小时,该方法还没有第二种简便。但是当取的索引值n超级大时,这种方法就非常方便了。时间复杂度在代码中标注出来了。

代码:

#!usr/bin/python2.7
# -*- coding=utf8 -*-
# @Time  : 18-1-3 下午2:53
# @Author : Cecil Charlie

import sys
import copy
sys.setrecursionlimit(1000) # 用来调整解释器默认最大递归深度


class Fibonacci(object):
  def __init__(self):
    pass

  def fibonacci1(self, n):
    '''
      原始的方法,时间复杂度为 o(2**n),因此代价较大
    :param n: 数列的第n个索引
    :return: 索引n对应的值
    '''
    if n < 1:
      return 0
    if n == 1 or n == 2:
      return 1
    return self.fibonacci1(n-1) + self.fibonacci1(n-2)

  @staticmethod
  def fibonacci2(n):
    """
      用循环替代递归,空间复杂度急剧降低,时间复杂度为o(n)
    """
    if n < 1:
      return 0
    if n == 1 or n == 2:
      return 1
    res = 1
    tmp1 = 0
    tmp2 = 1
    for _ in xrange(1, n):
      res = tmp1 + tmp2
      tmp1 = tmp2
      tmp2 = res
    return res

  def fibonacci3(self, n):
    """
      进一步减少迭代次数,采用矩阵求幂的方法,时间复杂度为o(log n),当然了,这种方法需要额外计算矩阵,计算矩阵的时间开销没有算在内.其中还运用到了位运算。
    """
    base = [[1, 1], [1, 0]]
    if n < 1:
      return 0
    if n == 1 or n == 2:
      return 1
    res = self.__matrix_power(base, n-2)
    return res[0][0] + res[1][0]

  def __matrix_power(self, mat, n):
    """
      求一个方阵的幂
    """
    if len(mat) != len(mat[0]):
      raise ValueError("The length of m and n is different.")
    if n < 0 or str(type(n)) != "<type 'int'>":
      raise ValueError("The power is unsuitable.")
    product, tmp = [], []
    for _ in xrange(len(mat)):
      tmp.append(0)
    for _ in xrange(len(mat)):
      product.append(copy.deepcopy(tmp))
    for _ in xrange(len(mat)):
      product[_][_] = 1
    tmp = mat
    while n > 0:
      if (n & 1) != 0: # 按位与的操作,在幂数的二进制位为1时,乘到最终结果上,否则自乘
        product = self.__multiply_matrix(product, tmp)
      tmp = self.__multiply_matrix(tmp, tmp)
      n >>= 1
    return product

  @staticmethod
  def __multiply_matrix(mat1, mat2):
    """
      矩阵计算乘积
    :param m: 矩阵1,二维列表
    :param n: 矩阵2
    :return: 乘积
    """
    if len(mat1[0]) != len(mat2):
      raise ValueError("Can not compute the product of mat1 and mat2.")
    product, tmp = [], []
    for _ in xrange(len(mat2[0])):
      tmp.append(0)
    for _ in xrange(len(mat1)):
      product.append(copy.deepcopy(tmp))
    for i in xrange(0, len(mat1)):
      for j in xrange(0, len(mat2[0])):
        for k in xrange(0, len(mat1[0])):
          if mat1[i][k] != 0 and mat2[k][j] != 0:
            product[i][j] += mat1[i][k] * mat2[k][j]
    return product


f = Fibonacci()
print f.fibonacci1(23)
print f.fibonacci2(23)
mat1 = [[2,4,5],[1,0,2],[4,6,9]]
mat2 = [[2,9],[1,0],[5,7]]
print f.fibonacci3(23)

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
基础的十进制按位运算总结与在Python中的计算示例
Jun 28 Python
python简单实现获取当前时间
Aug 27 Python
为什么选择python编程语言入门黑客攻防 给你几个理由!
Feb 02 Python
django进阶之cookie和session的使用示例
Aug 17 Python
Opencv+Python实现图像运动模糊和高斯模糊的示例
Apr 11 Python
使用celery执行Django串行异步任务的方法步骤
Jun 06 Python
Python pandas DataFrame操作的实现代码
Jun 21 Python
python UDP(udp)协议发送和接收的实例
Jul 22 Python
python wav模块获取采样率 采样点声道量化位数(实例代码)
Jan 22 Python
Python计算IV值的示例讲解
Feb 28 Python
如何使用Tkinter进行窗口的管理与设置
Jun 30 Python
如何基于python实现单目三维重建详解
Jun 25 Python
python实现汉诺塔算法
Mar 01 #Python
Python3中bytes类型转换为str类型
Sep 27 #Python
python求解数组中两个字符串的最小距离
Sep 27 #Python
Python开发的十个小贴士和技巧及长常犯错误
Sep 27 #Python
详解django中使用定时任务的方法
Sep 27 #Python
Python高级特性切片(Slice)操作详解
Sep 27 #Python
Python初学者需要注意的事项小结(python2与python3)
Sep 26 #Python
You might like
去除php注释和去除空格函数分享
2014/03/13 PHP
PHP计算百度地图两个GPS坐标之间距离的方法
2015/01/09 PHP
php实现html标签闭合检测与修复方法
2015/07/09 PHP
PHP判断密码强度的方法详解
2017/05/26 PHP
PHPstorm启用自动换行的方法详解(IDE)
2020/09/17 PHP
调试Node.JS的辅助工具(NodeWatcher)
2012/01/04 Javascript
用js小类库获取浏览器的高度和宽度信息
2012/01/15 Javascript
event.currentTarget与event.target的区别介绍
2012/12/31 Javascript
鼠标滚轮改变图片大小的示例代码
2013/11/20 Javascript
浅谈JSON中stringify 函数、toJosn函数和parse函数
2015/01/26 Javascript
jQuery操作表单常用控件方法小结
2015/03/23 Javascript
使用AngularJS 应用访问 Android 手机的图片库
2015/03/24 Javascript
基于JavaScript实现添加到购物车效果附源码下载
2016/08/22 Javascript
JavaScript 巧学巧用
2017/05/23 Javascript
基于vue2.0实现仿百度前端分页效果附实现代码
2018/10/30 Javascript
jQuery实现的简单日历组件定义与用法示例
2018/12/24 jQuery
详解Vue2 添加对scss的支持
2019/01/02 Javascript
JavaScript实现与使用发布/订阅模式详解
2019/01/19 Javascript
Vue.js组件通信之自定义事件详解
2019/10/19 Javascript
修改NPM全局模式的默认安装路径的方法
2020/12/15 Javascript
python映射列表实例分析
2015/01/26 Python
python3新特性函数注释Function Annotations用法分析
2016/07/28 Python
Python解析Excle文件中的数据方法
2018/10/23 Python
python矩阵的转置和逆转实例
2018/12/12 Python
python批量从es取数据的方法(文档数超过10000)
2018/12/27 Python
python中hasattr()、getattr()、setattr()函数的使用
2019/08/16 Python
css3实现input输入框颜色渐变发光效果代码
2014/04/02 HTML / CSS
综合办公室个人的自我评价
2013/12/22 职场文书
刊首寄语大全
2014/04/11 职场文书
小学生优秀评语大全
2014/04/22 职场文书
关于九一八事变的演讲稿2014
2014/09/17 职场文书
2015年招聘工作总结
2014/12/12 职场文书
2015庆祝七一建党节94周年活动总结
2015/03/20 职场文书
安全教育的主题班会
2015/08/13 职场文书
2019新员工心得体会
2019/06/25 职场文书
如何用python识别滑块验证码中的缺口
2021/04/01 Python