斐波那契数列的三种实现方法

    斐波那契数列是学习算法碰到的,以自己当前的知识面还不足以想到通过升高一个维度来降低算法的时间复杂度.

昨天再看剑指offer的时候,在面试题9中提到了三种实现计算斐波那契数列的方法.在这里实现三种做法貌似还有一个O(1)的计算方法,也就是斐波那契数列是可以直接推到出来的.

    1.常规的递归算法

     

def fib(n):
    if n <= 0:
        return 0
    if n == 1:
        return 1
    return fib(n - 1) + fib(n - 2)
print (fib(5))

   这种递归算法有大量的重复计算
      以f(4)为例
      f(4) = f(3) + f(2) ;
      f(3) = f(2) + f(1)
      f(2) = f(1) + f(0)
      时间复杂度是以指数的形式增长,O(2^n)
     如果面试时候这样写,90%的概率你已经gg了


    2.循环形式
          递归主要是做了大量的重复计算,如果把每一项计算出来后直接保存,使用的时候再去调用,这样就减少那些不必要的计算.    

           

def f(n):
    a, b = 0, 1
    while n:
        a, b = b, a + b
        n -= 1
    return a
print (f(4))
 

 只要记录好前面的,后面的计算就直接用了.时间复杂度是O(N)

  

    3.以矩阵的形式计算
        就是通过增加维度降低时间复杂度
        可以通过数学归纳法得出
        [[f(n), f(n - 1)], [f(n - 1), f(n - 2)]] = [[1, 1], [1, 0]]^(n - 1) 
        所以得出这个结论之后,要做的就是计算计算矩阵[[1,1], [1,0]]^(n - 1)
        这可以考虑   
       a^n = a^(n /2 ) * a^(n / 2) if n % 2== 0
       a^n  = a^ (n - 1) * a^ (n - 1) * a if n%2 != 0
        得到这些信息,就可以计算了

     

def mul(l1, trix):
    return [sum(list(map(lambda x:x[0] * x[1], zip(l1, trix[:][0])))),\
            sum(list(map(lambda x:x[0] *x[1], zip(l1, trix[:][1]))))]

def matrixMulti(trix1, trix2):
    return [mul(trix1[0], trix2), mul(trix1[1], trix2)]


def main(n):
    basicMatrix = [[1, 1], [1, 0]]
    # 单位1
    ans = [[1, 0], [0, 1]]
    if n == 0:
        return 0
    if n == 1:
        return 1

    while n:
        # n是奇数,先做一个乘法
        if n&1:
            ans = matrixMulti(ans, basicMatrix)
        basicMatrix = matrixMulti(basicMatrix, basicMatrix)
        n >>= 1
    return ans[0][1]

for i in  range(10):
    print (main(i))

 就可以得到最终的结果
 这种基于递归用O(log(n))的求得n次方的方法值得重视.

    

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值