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 相关文章推荐
pygame学习笔记(3):运动速率、时间、事件、文字
Apr 15 Python
pygame学习笔记(6):完成一个简单的游戏
Apr 15 Python
Python使用lxml模块和Requests模块抓取HTML页面的教程
May 16 Python
Python正则表达式使用经典实例
Jun 21 Python
在Python的一段程序中如何使用多次事件循环详解
Sep 07 Python
python遍历文件夹下所有excel文件
Jan 03 Python
python自动发邮件库yagmail的示例代码
Feb 23 Python
Python 模拟动态产生字母验证码图片功能
Dec 24 Python
python使用gdal对shp读取,新建和更新的实例
Mar 10 Python
在ipython notebook中使用argparse方式
Apr 20 Python
基于python3.7利用Motor来异步读写Mongodb提高效率(推荐)
Apr 29 Python
Python基础教程之输入输出和运算符
Jul 26 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发电子邮件
2006/10/09 PHP
php str_pad 函数使用详解
2009/01/13 PHP
将一维或多维的数组连接成一个字符串的php代码
2010/08/08 PHP
Php Ctemplate引擎开发相关内容
2012/03/03 PHP
php计算指定目录下文件占用空间的方法
2015/03/13 PHP
新页面打开实际尺寸的图片
2006/08/25 Javascript
帮助避免错误的Javascript陷阱清单
2009/05/31 Javascript
javascript实现倒计时并弹窗提示特效
2015/06/05 Javascript
推荐10 个很棒的 jQuery 特效代码
2015/10/04 Javascript
JavaScript中关联原型链属性特性
2016/02/13 Javascript
javascript轻量级库createjs使用Easel实现拖拽效果
2016/02/19 Javascript
IE8 内存泄露(内存一直增长 )的原因及解决办法
2016/04/06 Javascript
easyUI实现(alert)提示框自动关闭的实例代码
2016/11/07 Javascript
文件上传,iframe跨域数据提交的实现
2016/11/18 Javascript
Javascript 制作图形验证码实例详解
2016/12/22 Javascript
javascript将json格式数组下载为excel表格的方法
2017/12/22 Javascript
angular2/ionic2 实现搜索结果中的搜索关键字高亮的示例
2018/08/17 Javascript
vue 配置多页面应用的示例代码
2018/10/22 Javascript
Vue-cli3.X使用px2 rem遇到的问题及解决方法
2019/08/08 Javascript
JavaScript隐式类型转换代码实例
2020/05/29 Javascript
基于 Vue 的 Electron 项目搭建过程图文详解
2020/07/22 Javascript
VUE动态生成word的实现
2020/07/26 Javascript
nuxt.js写项目时增加错误提示页面操作
2020/11/05 Javascript
vue实现简易计算器功能
2021/01/20 Vue.js
对pandas进行数据预处理的实例讲解
2018/04/20 Python
浅谈python中str字符串和unicode对象字符串的拼接问题
2018/12/04 Python
python爬虫之urllib,伪装,超时设置,异常处理的方法
2018/12/19 Python
简单了解Django ORM常用字段类型及参数配置
2020/01/07 Python
Xadmin+rules实现多选行权限方式(级联效果)
2020/04/07 Python
Python如何读写字节数据
2020/08/05 Python
德国排名第一的主题公园门票网站:Attraction Tickets Direct
2019/09/09 全球购物
MIXIT官网:俄罗斯最大的化妆品公司之一
2020/01/25 全球购物
网络信息安全承诺书
2014/03/26 职场文书
上班迟到检讨书范文300字
2014/11/02 职场文书
幼儿园教师自我评价
2015/03/04 职场文书
月考总结与反思
2015/10/22 职场文书