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通过线程实现定时器timer的方法
Mar 16 Python
Python之父谈Python的未来形式
Jul 01 Python
Python实现的单向循环链表功能示例
Nov 10 Python
使用Python如何测试InnoDB与MyISAM的读写性能
Sep 18 Python
python 列表递归求和、计数、求最大元素的实例
Nov 28 Python
对Python模块导入时全局变量__all__的作用详解
Jan 11 Python
Python实现从SQL型数据库读写dataframe型数据的方法【基于pandas】
Mar 18 Python
Python正则表达式匹配和提取IP地址
Jun 06 Python
解决pycharm remote deployment 配置的问题
Jun 27 Python
Python 正则表达式爬虫使用案例解析
Sep 23 Python
tensorflow多维张量计算实例
Feb 11 Python
Python基础之字典常见操作经典实例详解
Feb 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 网页过期时间的控制代码
2009/06/29 PHP
理解PHP中的stdClass类
2014/04/18 PHP
PHP添加文字水印或图片水印的水印类完整源代码与使用示例
2019/03/18 PHP
PHP 文件上传限制问题
2019/09/01 PHP
PHP实现微信提现功能(微信商城)
2019/11/21 PHP
短信提示使用 特效
2007/01/19 Javascript
js 操作css实现代码
2009/06/11 Javascript
JS input文本框禁用右键和复制粘贴功能的代码
2010/04/15 Javascript
关于js datetime的那点事
2011/11/15 Javascript
JavaScript中String.prototype用法实例
2015/05/20 Javascript
jQuery幻灯片特效代码分享--鼠标滑过按钮时切换(2)
2020/11/18 Javascript
jQuery仿淘宝网产品品牌隐藏与显示效果
2015/09/01 Javascript
Bootstrap轮播加上css3动画,炫酷到底!
2015/12/22 Javascript
非常酷炫的Bootstrap图片轮播动画
2016/05/27 Javascript
微信js-sdk分享功能接口常用逻辑封装示例
2016/10/13 Javascript
基于js实现checkbox批量选中操作
2016/11/22 Javascript
鼠标点击input,显示瞬间的边框颜色,对之修改与隐藏实例
2016/12/26 Javascript
详解Sea.js中Module.exports和exports的区别
2017/02/12 Javascript
jQuery EasyUI结合zTree树形结构制作web页面
2017/09/01 jQuery
微信小程序实现跟随菜单效果和循环嵌套加载数据
2017/11/21 Javascript
解决vue项目运行npm run serve报错的问题
2020/10/26 Javascript
python中的错误处理
2016/04/10 Python
Python手机号码归属地查询代码
2016/05/04 Python
浅谈flask截获所有访问及before/after_request修饰器
2018/01/18 Python
查看django执行的sql语句及消耗时间的两种方法
2018/05/29 Python
对Python 内建函数和保留字详解
2018/10/15 Python
django的ORM操作 删除和编辑实现详解
2019/07/24 Python
一行python实现树形结构的方法
2019/08/09 Python
python 双循环遍历list 变量判断代码
2020/05/04 Python
Python实现进度条和时间预估的示例代码
2020/06/02 Python
浅析Python面向对象编程
2020/07/10 Python
傲慢与偏见读书笔记
2015/06/29 职场文书
2016年记者节感言
2015/12/08 职场文书
五年级语文教学反思
2016/03/03 职场文书
python使用tkinter实现透明窗体上绘制随机出现的小球(实例代码)
2021/05/17 Python
使用Redis实现分布式锁的方法
2022/06/16 Redis