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 命令行参数sys.argv
Sep 06 Python
编写Python的web框架中的Model的教程
Apr 29 Python
python中list常用操作实例详解
Jun 03 Python
python实现BackPropagation算法
Dec 14 Python
python 3.6.5 安装配置方法图文教程
Sep 18 Python
opencv实现图片模糊和锐化操作
Nov 19 Python
python 实现简单的FTP程序
Dec 27 Python
python学生管理系统的实现
Apr 05 Python
python安装和pycharm环境搭建设置方法
May 27 Python
什么是python的函数体
Jun 19 Python
Virtualenv 搭建 Py项目运行环境的教程详解
Jun 22 Python
Python return语句如何实现结果返回调用
Oct 15 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下图片文字混合水印与缩略图实现代码
2009/12/11 PHP
php实现的简单日志写入函数
2015/03/31 PHP
PHP快速推送微信模板消息
2017/04/14 PHP
ThinkPHP中create()方法自动验证表单信息
2017/04/28 PHP
快速解决PHP调用Word组件DCOM权限的问题
2017/12/27 PHP
比较全的JS checkbox全选、取消全选、删除功能代码
2008/12/19 Javascript
javascript权威指南 学习笔记之变量作用域分享
2011/09/28 Javascript
javascript跑马灯悬停放大效果实现代码
2012/12/12 Javascript
jquery uploadify 在FF下无效的解决办法
2014/09/26 Javascript
jquery实现勾选复选框触发事件给input赋值
2015/02/01 Javascript
Javascript中For In语句用法实例
2015/05/14 Javascript
Javascript中Array用法实例分析
2015/06/13 Javascript
jQuery实现获取元素索引值index的方法
2016/09/18 Javascript
基于Layer+jQuery的自定义弹框
2020/05/26 Javascript
bootstrap weebox 支持ajax的模态弹出框
2017/02/23 Javascript
微信小程序实战之自定义模态弹窗(8)
2017/04/18 Javascript
vue修改vue项目运行端口号的方法
2017/08/04 Javascript
微信小程序异步处理详解
2017/11/10 Javascript
ES6与CommonJS中的模块处理的区别
2018/06/13 Javascript
JS实现的排列组合算法示例
2019/07/16 Javascript
Node中对非阻塞I/O、事件循环的知识点总结
2020/01/05 Javascript
[04:52]第二届DOTA2亚洲邀请赛主赛事第一天比赛集锦:OG娜迦海妖放大配合谜团大中3人
2017/04/02 DOTA
python使用cStringIO实现临时内存文件访问的方法
2015/03/26 Python
Python把csv数据写入list和字典类型的变量脚本方法
2018/06/15 Python
Python使用numpy产生正态分布随机数的向量或矩阵操作示例
2018/08/22 Python
对Python 内建函数和保留字详解
2018/10/15 Python
Python: 传递列表副本方式
2019/12/19 Python
Python实现检测文件的MD5值来查找重复文件案例
2020/03/12 Python
Python编写单元测试代码实例
2020/09/10 Python
python关于倒排列的知识点总结
2020/10/13 Python
Laura Mercier官网:彩妆大师罗拉玛斯亚的化妆品牌
2018/01/04 全球购物
J2EE面试题大全
2016/08/06 面试题
财务总监管理岗位职责
2014/03/08 职场文书
刑事上诉状范文
2015/05/22 职场文书
MySQL之MyISAM存储引擎的非聚簇索引详解
2022/03/03 MySQL
Mysql排查分析慢sql之explain实战案例
2022/04/19 MySQL