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中的迭代器漫谈
Feb 03 Python
详解Python的Django框架中的Cookie相关处理
Jul 22 Python
Python学习入门之区块链详解
Jul 25 Python
python使用tensorflow保存、加载和使用模型的方法
Jan 31 Python
PyQt5 实现字体大小自适应分辨率的方法
Jun 18 Python
Python3enumrate和range对比及示例详解
Jul 13 Python
关于PyTorch源码解读之torchvision.models
Aug 17 Python
如何解决django-celery启动后迅速关闭
Oct 16 Python
解决python replace函数替换无效问题
Jan 18 Python
tensorflow2.0的函数签名与图结构(推荐)
Apr 28 Python
常用的10个Python实用小技巧
Aug 10 Python
Python包管理工具pip的15 个使用小技巧
May 17 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 curl 获取响应的状态码的方法
2014/01/13 PHP
主流PHP框架的优缺点对比分析
2014/12/25 PHP
php随机显示指定文件夹下图片的方法
2015/07/13 PHP
微信公众平台开发之天气预报功能
2015/08/31 PHP
Javascript中定义方法的另类写法(批量定义js对象的方法)
2011/02/25 Javascript
各浏览器对link标签onload/onreadystatechange事件支持的差异分析
2011/04/27 Javascript
javascript:文字不间断向左移动的实例代码
2013/08/08 Javascript
javascript 密码框防止用户粘贴和复制的实现代码
2014/02/17 Javascript
JS实现的通用表单验证插件完整实例
2015/08/20 Javascript
jQuery.trim() 函数及trim()用法详解
2015/10/26 Javascript
基于javascript实现浏览器滚动条快到底部时自动加载数据
2015/11/30 Javascript
js正则表达式验证密码强度【推荐】
2017/03/03 Javascript
详解Vue 非父子组件通信方法(非Vuex)
2017/05/24 Javascript
使用vue点击li,获取当前点击li父辈元素的属性值方法
2018/09/12 Javascript
js面向对象方式实现拖拽效果
2021/03/03 Javascript
Python正则表达式的使用范例详解
2014/08/08 Python
在Python下使用Txt2Html实现网页过滤代理的教程
2015/04/11 Python
python检查指定文件是否存在的方法
2015/07/06 Python
Python 由字符串函数名得到对应的函数(实例讲解)
2017/08/10 Python
python操作excel的方法
2018/08/16 Python
python实现信号时域统计特征提取代码
2020/02/26 Python
详解在Python中使用Torchmoji将文本转换为表情符号
2020/07/27 Python
matplotlib 使用 plt.savefig() 输出图片去除旁边的空白区域
2021/01/05 Python
html5新特性与用法大全
2018/09/13 HTML / CSS
Viking Direct爱尔兰:办公用品和家具
2019/11/21 全球购物
某公司C#程序员面试题笔试题
2014/05/26 面试题
经典演讲稿范文
2013/12/30 职场文书
旷课检讨书大全
2014/01/21 职场文书
棉花姑娘教学反思
2014/02/15 职场文书
规划编制实施方案
2014/03/15 职场文书
环保守法证明
2015/06/24 职场文书
初中体育教学随笔
2015/08/15 职场文书
毕业生求职自荐信(2016最新版)
2016/01/28 职场文书
Go语言基础知识点介绍
2021/07/04 Golang
Ruby使用Mysql2连接操作MySQL
2022/04/19 Ruby
Java实现简单小画板
2022/06/10 Java/Android