algorithm - 它要求获得斐波那契数列的一项。无法弄清楚为什么我的代码总是超时

标签 algorithm python-3.x fibonacci

这是 Hackerrank 中的一个问题。链接在这里:fibonacci-finding-easy

给出递归序列F(n+2)=F(n+1)+F(n)的两个初值F(0),F(1)分别赋给A,B求它的第 N 项,输出模数 (10^9 + 7)。我知道经典的解决方法是使用快速矩阵乘法。我用 Python3 编写它。我的 IDE 中的测试没有问题。但我不知道不知道为什么我的代码总是超时。这是我的代码:

def mul22(a, b):
    r = [[0, 0], [0, 0]]
    r[0][0] = (a[0][0] * b[0][0] + a[0][1] * b[1][0]) % 1000000007
    r[0][1] = (a[0][0] * b[0][1] + a[0][1] * b[1][1]) % 1000000007
    r[1][0] = (a[1][0] * b[0][0] + a[1][1] * b[1][0]) % 1000000007
    r[1][1] = (a[1][0] * b[0][1] + a[1][1] * b[1][1]) % 1000000007
    return r

def MatrixPow(A, n):
    if n == 1:
        return A
    if n % 2 == 1:
        return mul22(mul22(MatrixPow(A, n // 2),MatrixPow(A, n // 2)), A)
    return mul22(MatrixPow(A, n // 2), MatrixPow(A, n // 2))

for i in range(int(input())):
    A,B,N= map(int,input().split())
    if N == 1:
        print(B % 1000000007)
    else:
        print(mul22(MatrixPow([[1, 1],[1, 0]], N - 1),[[B,1],[A,1]])[0][0] % 1000000007)

首先我认为问题是 10 ** 9 + 7 使整个递归过程如此缓慢。但是我在我的 IDE 中测试了很多次,一切正常,不存在 TLE。有什么我遗漏的吗?

最佳答案

您编写 MatrixPow 函数的方式实际上并未在 O(log(n)) 中运行。它的运行时间是O(N)

考虑这个幂函数:

def power_n(a,b):
    print 1
    if b==0:
        return 1
    if b%2==1:
        return (((power_n(a,b/2)*power_n(a,b/2))%MOD)*a)%MOD
    return (power_n(a,b/2)*power_n(a,b/2))%MOD

还有这个:

def power_log(a,b):
    print 2
    if b==0:
        return 1
    k = power_log(a,b/2)
    if b%2==1:
        return (((k*k)%MOD)*a)%MOD
    return (k*k)%MOD

第一种和第二种的区别在于,在第二种情况下我们只遍历整个递归树一次(因为一旦我们有了某个值,我们就保存它),而在第一种情况下,我们一次又一次地计算它。

虽然看起来一样,但第一个函数类似于传统循环,运行时间为 O(n),而第二个函数实际上是幂函数,运行时间为 O(log n)

PS:n 表示b,即。权力

编辑:

分析: (我只是在两个函数中都添加了打印语句并运行了它,这是结果)

power_n(6,20)
    1
    1
    1
    1
    1
    1
    1
    1
    1
    1
    1
    1
    1
    1
    1
    1
    1
    1
    1
    1
    1
    1
    1
    1
    1
    1
    1
    1
    1
    1
    1
    1
    1
    1
    1
    1
    1
    1
    1
    1
    1
    1
    1
    1
    1
    1
    1
    1
    1
    1
    1
    1
    1
    1
    1
    1
    1
    1
    1
    1
    1
    1
    1
    Out[22]: 414469870

power_log(6,20)
    2
    2
    2
    2
    2
    2
    Out[25]: 414469870

查看函数调用次数的差异。

关于algorithm - 它要求获得斐波那契数列的一项。无法弄清楚为什么我的代码总是超时,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41181103/

相关文章:

python - 一个全为 0 和 1 的未知数组或大小找到以 XOR 函数 python 开头的数组

python - 为 "Lights out"变体生成切换矩阵

python - 错误: Could not import “file_name” in flask

c++ - 'cout' 语句未被执行

c++ - 我可以做些什么来改进我的斐波那契数生成器?

php - 在 php while 循环的下一个循环中使用减少的变量

java - 需要特定总和的数组元素的最佳组合,且浪费最少

python - numpy.ndarray : converting to a "normal" class

python - 向 Python 类添加属性时如何更新 pickle 对象

c - 如何修复 SIGSEGV? (在斐波那契数列中处理高达 1000000 的大值时出错)