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 相关文章推荐
精确查找PHP WEBSHELL木马的方法(1)
Apr 12 Python
Python中操作MySQL入门实例
Feb 08 Python
Python实现生成随机数据插入mysql数据库的方法
Dec 25 Python
Python实现的查询mysql数据库并通过邮件发送信息功能
May 17 Python
python3 拼接字符串的7种方法
Sep 12 Python
python利用ffmpeg进行录制屏幕的方法
Jan 10 Python
python3使用print打印带颜色的字符串代码实例
Aug 22 Python
python实现小世界网络生成
Nov 21 Python
Python基于当前时间批量创建文件
May 07 Python
深入了解python列表(LIST)
Jun 08 Python
Python3.8安装Pygame教程步骤详解
Aug 14 Python
python 8种必备的gui库
Aug 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连接MySQL代码的参数说明
2008/06/07 PHP
PHP常用函数小技巧
2008/09/11 PHP
php 获取本机外网/公网IP的代码
2010/05/09 PHP
php数组函数序列 之array_count_values() 统计数组中所有值出现的次数函数
2011/10/29 PHP
浅析虚拟主机服务器php fsockopen函数被禁用的解决办法
2013/08/07 PHP
PHP基于CURL进行POST数据上传实例
2014/11/10 PHP
PHP中两个float(浮点数)比较实例分析
2015/09/27 PHP
PHP的反射机制实例详解
2017/03/29 PHP
CSS+JS构建的图片查看器
2006/07/22 Javascript
JS异常处理的一个想法(sofish)
2013/03/14 Javascript
JS保留小数点(四舍五入、四舍六入)实现思路及实例
2013/04/25 Javascript
javascript页面动态显示时间变化示例代码
2013/12/18 Javascript
Node.js文件操作详解
2014/08/16 Javascript
省市联动效果的简单实现代码(推荐)
2016/06/06 Javascript
微信JSSDK调用微信扫一扫功能的方法
2017/07/25 Javascript
解决vue2中使用axios http请求出现的问题
2018/03/05 Javascript
Vue.js项目中管理每个页面的头部标签的两种方法
2018/06/25 Javascript
vue路由跳转传参数的方法
2019/05/06 Javascript
python实现数通设备端口监控示例
2014/04/02 Python
简单介绍Python中的JSON使用
2015/04/28 Python
Python内置函数OCT详解
2016/11/09 Python
ubuntu安装sublime3并配置python3环境的方法
2018/03/15 Python
python简单操作excle的方法
2018/09/12 Python
Python 互换字典的键值对实例
2019/02/12 Python
Python selenium 加载并保存QQ群成员,去除其群主、管理员信息的示例代码
2020/05/28 Python
Python新手学习标准库模块命名
2020/05/29 Python
python 使用tkinter+you-get实现视频下载器
2020/11/17 Python
Tech21美国/加拿大:英国NO.1防摔保护壳品牌
2018/01/20 全球购物
美国温暖商店:The Warming Store
2018/12/15 全球购物
标准毕业生自荐信范文
2013/11/04 职场文书
电子技术专业中专生的自我评价
2013/12/17 职场文书
运动会方阵解说词
2014/02/12 职场文书
红旗渠导游词
2015/02/09 职场文书
MySQL infobright的安装步骤
2021/04/07 MySQL
Javascript 解构赋值详情
2021/11/17 Javascript
Nginx文件已经存在全局反向代理问题排查记录
2022/07/15 Servers