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线程中对join方法的运用的教程
Apr 09 Python
python基于pyDes库实现des加密的方法
Apr 29 Python
Python中类的初始化特殊方法
Dec 01 Python
PyQt5每天必学之组合框
Apr 20 Python
Python 实现选择排序的算法步骤
Apr 22 Python
python opencv3实现人脸识别(windows)
May 25 Python
对python dataframe逻辑取值的方法详解
Jan 30 Python
python将视频转换为全字符视频
Apr 26 Python
Python命令行click参数用法解析
Dec 19 Python
Python threading.local代码实例及原理解析
Mar 16 Python
Django 允许局域网中的机器访问你的主机操作
May 13 Python
Python实现像awk一样分割字符串
Sep 15 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
深入file_get_contents函数抓取内容失败的原因分析
2013/06/25 PHP
PHP会话控制:Session与Cookie详解
2014/09/27 PHP
JavaScript 给汉字排序实例代码
2008/06/28 Javascript
js arguments.callee的应用代码
2009/05/07 Javascript
HTML页面滚动时获取离页面顶部的距离2种实现方法
2013/09/05 Javascript
JavaScript中的闭包(Closure)详细介绍
2014/12/30 Javascript
EasyUi datagrid 实现表格分页
2015/02/10 Javascript
深入学习AngularJS中数据的双向绑定机制
2016/03/04 Javascript
【经验总结】编写JavaScript代码时应遵循的14条规律
2016/06/20 Javascript
AngularJS控制器详解及示例代码
2016/08/16 Javascript
浅谈angular2 组件的生命周期钩子
2017/08/12 Javascript
vue-router实现组件间的跳转(参数传递)
2017/11/07 Javascript
浅谈React 服务器端渲染的使用
2018/05/08 Javascript
小程序自定义单页面、全局导航栏的实现代码
2019/03/15 Javascript
JS获取本地地址及天气的方法实例小结
2019/05/10 Javascript
[03:37]2014DOTA2国际邀请赛 主赛事第一日胜者组TOPPLAY
2014/07/19 DOTA
Python中多线程的创建及基本调用方法
2016/07/08 Python
Pandas 数据处理,数据清洗详解
2018/07/10 Python
python3.7.0的安装步骤
2018/08/27 Python
在python中利用最小二乘拟合二次抛物线函数的方法
2018/12/29 Python
对pyqt5之menu和action的使用详解
2019/06/20 Python
opencv调整图像亮度对比度的示例代码
2019/09/27 Python
pandas中read_csv的缺失值处理方式
2019/12/19 Python
python中time tzset()函数实例用法
2021/02/18 Python
韩国三星旗下的一家超市连锁店:Home Plus
2016/07/30 全球购物
Nike爱尔兰官方网站:Nike.com (IE)
2018/03/12 全球购物
巴西化妆品商店:Lojas Rede
2019/07/26 全球购物
美国小蜜蜂Burt’s Bees德国官网:天然唇部、皮肤和身体护理产品
2020/06/14 全球购物
财务会计专业毕业生自荐信
2013/10/02 职场文书
自动化专业毕业生自荐信
2013/11/01 职场文书
高一数学教学反思
2014/02/07 职场文书
职工擅自离岗检讨书
2014/09/23 职场文书
大学生个人学习总结
2015/02/15 职场文书
Nginx服务器添加Systemd自定义服务过程解析
2021/03/31 Servers
使用Vue3+Vant组件实现App搜索历史记录功能(示例代码)
2021/06/09 Vue.js
spring IOC容器的Bean管理XML自动装配过程
2022/05/30 Java/Android