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 30 Python
基于Python的接口测试框架实例
Nov 04 Python
基于python内置函数与匿名函数详解
Jan 09 Python
python 产生token及token验证的方法
Dec 26 Python
Python中按值来获取指定的键
Mar 04 Python
numpy.transpose()实现数组的转置例子
Dec 02 Python
Python lxml模块的基本使用方法分析
Dec 21 Python
python如何实现复制目录到指定目录
Feb 13 Python
Python3.x+pyqtgraph实现数据可视化教程
Mar 14 Python
python操作yaml说明
Apr 08 Python
Django实现前台上传并显示图片功能
May 29 Python
Python数据模型与Python对象模型的相关总结
Jan 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/07/08 PHP
ftp类(example.php)
2006/10/09 PHP
下载文件的点击数回填
2006/10/09 PHP
彻底杜绝PHP的session cookie错误
2009/08/09 PHP
PHP实现求解最长公共子串问题的方法
2017/11/17 PHP
Laravel 集成微信用户登录和绑定的实现
2019/12/27 PHP
比较简单的异步加载JS文件的代码
2009/07/18 Javascript
jquery select操作的日期联动实现代码
2009/12/06 Javascript
js实现页面打印功能实例代码(附去页眉页脚功能代码)
2009/12/15 Javascript
Jquery Select操作方法集合脚本之家特别版
2010/05/17 Javascript
js+html+css实现鼠标移动div实例
2013/01/30 Javascript
bootstrap data与jquery .data
2014/07/07 Javascript
JS基础随笔(菜鸟必看篇)
2016/07/13 Javascript
学习Javascript闭包(Closure)知识
2016/08/07 Javascript
NodeJS整合银联网关支付(DEMO)
2016/11/09 NodeJs
vue插件vue-resource的使用笔记(小结)
2017/08/04 Javascript
基于js原生和ajax的get和post方法以及jsonp的原生写法实例
2017/10/16 Javascript
VueAwesomeSwiper在VUE中的使用以及遇到的一些问题
2018/01/11 Javascript
微信小程序开发之点击按钮退出小程序的实现方法
2019/04/26 Javascript
JS实现购物车基本功能
2020/11/08 Javascript
浅谈Python2.6和Python3.0中八进制数字表示的区别
2017/04/28 Python
python使用Tkinter实现在线音乐播放器
2018/01/30 Python
Python 创建空的list,以及append用法讲解
2018/05/04 Python
PyCharm中Matplotlib绘图不能显示UI效果的问题解决
2020/03/12 Python
纯CSS3绘制打火机动画火焰效果
2016/07/18 HTML / CSS
屈臣氏泰国官网:Watsons TH
2021/02/23 全球购物
《埃及的金字塔》教学反思
2014/04/07 职场文书
《雪儿》教学反思
2014/04/17 职场文书
个人安全承诺书
2014/05/22 职场文书
党员群众路线剖析材料
2014/10/08 职场文书
老人节标语大全
2014/10/08 职场文书
学前班语言教学计划
2015/01/20 职场文书
教师培训简讯
2015/07/20 职场文书
小学大队长竞选稿
2015/11/20 职场文书
python和C/C++混合编程之使用ctypes调用 C/C++的dll
2022/04/29 Python
Python循环之while无限迭代
2022/04/30 Python