斐波那契数列及其变种 装饰器版本和矩阵加速

from functools import reduce
from functools import wraps


def memo(func):
    cache = {}

    @wraps(func)
    def wrap(*args):
        if args not in cache:
            cache[args] = func(*args)
        return cache[args]

    return wrap


@memo
def fib(i):
    if i <= 2:
        return 1
    return fib(i - 1) + fib(i - 2)


print(fib(10))

# encoding=utf-8


"""
   标准库的做法
"""


class Solution(object):
    # 矩阵相乘
    def mul(self, a, b):
        r = [[0, 0], [0, 0]]
        r[0][0] = a[0][0] * b[0][0] + a[0][1] * b[1][0]
        r[0][1] = a[0][0] * b[0][1] + a[0][1] * b[1][1]
        r[1][0] = a[1][0] * b[0][0] + a[1][1] * b[1][0]
        r[1][1] = a[1][0] * b[0][1] + a[1][1] * b[1][1]
        return r

    # 递归加速计算斐波那契数列 O(n^2) -> O(logn)
    def helper(self, n):
        if n == 0:
            return [[1, 0], [0, 1]]
        if n == 1:
            return [[1, 1], [1, 0]]
        if n & 1 == 0:
            return self.mul(self.helper(n // 2), self.helper(n // 2))
        else:
            return reduce(self.mul, [self.helper((n - 1) // 2), self.helper((n - 1) // 2), [[1, 1], [1, 0]]])

    def fib(self, N):
        if N == 0 or N == 1:
            return N
        return self.helper(N - 1)[0][0]


if __name__ == "__main__":
    for i in range(2, 11):
        print(i, Solution().fib(i))

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值