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编程中三条常用的技巧
May 11 Python
深入源码解析Python中的对象与类型
Dec 11 Python
关于Python 3中print函数的换行详解
Aug 08 Python
python 删除非空文件夹的实例
Apr 26 Python
PyCharm的设置方法和第一个Python程序的建立
Jan 16 Python
Python实现爬取马云的微博功能示例
Feb 16 Python
python算法与数据结构之冒泡排序实例详解
Jun 22 Python
Python 中的参数传递、返回值、浅拷贝、深拷贝
Jun 25 Python
Flask框架重定向,错误显示,Responses响应及Sessions会话操作示例
Aug 01 Python
Python 分布式缓存之Reids数据类型操作详解
Jun 24 Python
python3.9.1环境安装的方法(图文)
Feb 02 Python
Python基础之pandas数据合并
Apr 27 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网页游戏学习之Xnova(ogame)源码解读(十三)
2014/06/26 PHP
php解析url并得到url中的参数及获取url参数的四种方式
2015/10/26 PHP
php设计模式之策略模式应用案例详解
2019/06/17 PHP
让 JavaScript 轻松支持函数重载 (Part 2 - 实现)
2009/08/04 Javascript
对frameset、frame、iframe的js操作示例代码
2013/08/16 Javascript
js获取会话框prompt的返回值的方法
2015/01/10 Javascript
js 判断所选时间(或者当前时间)是否在某一时间段的实现代码
2015/09/05 Javascript
详解javascript实现瀑布流绝对式布局
2016/01/29 Javascript
canvas实现手机端用来上传用户头像的代码
2016/10/20 Javascript
JS正则匹配URL网址的方法(可匹配www,http开头的一切网址)
2017/01/06 Javascript
Vue条件循环判断+计算属性+绑定样式v-bind的实例
2018/09/18 Javascript
js时间戳转yyyy-MM-dd HH-mm-ss工具类详解
2019/04/30 Javascript
Django 根据数据模型models创建数据表的实例
2018/05/27 Python
python 读取文本文件的行数据,文件.splitlines()的方法
2018/07/12 Python
对tensorflow 的模型保存和调用实例讲解
2018/07/28 Python
Python编程图形库之Pillow使用方法讲解
2018/12/28 Python
python障碍式期权定价公式
2019/07/19 Python
python数组循环处理方法
2019/08/26 Python
下载官网python并安装的步骤详解
2019/10/12 Python
python中自带的三个装饰器的实现
2019/11/08 Python
浅谈在JupyterNotebook下导入自己的模块的问题
2020/04/16 Python
Python格式化输出--%s,%d,%f的代码解析
2020/04/29 Python
CSS3控制HTML元素动画效果
2014/02/08 HTML / CSS
Oakley西班牙官方商店:太阳眼镜和男女运动服
2019/04/26 全球购物
请说出以下代码输出什么
2013/08/30 面试题
体育教育专业自荐信范文
2013/12/20 职场文书
大堂副理的岗位职责范文
2014/02/17 职场文书
节约电力资源的建议书
2014/03/12 职场文书
消防标语大全
2014/06/07 职场文书
设计师求职信
2014/07/01 职场文书
主题党日活动总结
2014/07/08 职场文书
2014年秋季新学期寄语
2014/08/02 职场文书
2014年妇联工作总结
2014/11/21 职场文书
安全生产隐患排查制度
2015/08/05 职场文书
2015年国庆放假通知范文
2015/08/18 职场文书
八年级作文之我的母亲
2019/12/10 职场文书