斐波纳契系列在PHP中的第n个数字与O(log N)

时间:2016-03-31 11:11:04

标签: php performance fibonacci space-complexity code-complexity

寻找复杂性代码为O(log N)的解决方案。 space complexity将为O(1)

我试过了

function fib($a, $b, $N) {

    $c = "";
    if ($N == 0) {
        return intval($a);
    } else if ($N == 1) {
        return intval($b);
    } else {
        for ($i = 1; $i <= $N - 1; $a = $b, $b = $c, $i++) {
            $c = ($a) + ($b);
        }
    }
    return intval($c);
}

原始问题是

enter image description here

1 个答案:

答案 0 :(得分:0)

因此,关于您的代码,您已经实现了O(1)的空间复杂性,但您的时间复杂度仍为O(n),因为仍需要n执行for循环才能找到{ {1}}数字。

其次,您尝试创建的函数可以生成斐波那契序列,但也可以使用相同的原理生成其他序列,但从不同的数字开始。

我们需要做的第一件事就是在不到线性的时间内解决这个问题,就是用矩阵来表示序列,如下所示:

我们可以从两个初始数字左侧创建矩阵。然后我们可以将它提升到n'th幂,我们将在结果矩阵的左上角得到我们想要的数字。

PHP中的简单实现可能如下所示:

n-1

但是,正如您可能看到的那样,我们仍然没有摆脱for循环,这意味着我们仍然有/** * Takes two 2x2 matrices as parameters, multiplies them and returns the result. */ function multiply_matrix(array $a, array $b) { return [ [ $a[0][0]*$b[0][0] + $a[0][1]*$b[1][0], $a[0][0]*$b[0][1] + $a[0][1]*$b[1][1] ], [ $a[1][0]*$b[0][0] + $a[1][1]*$b[1][0], $a[1][0]*$b[0][1] + $a[1][1]*$b[1][1] ] ]; } /** * Multiplies a 2x2 matrix to the n'th power */ function power_of_matrix(array $matr, $n) { $result = $matr; for ($i = 1; $i < $n; ++$i) { $result = multiply_matrix($result, $matr); } return $result; } function gf($a, $b, $n) { if ($n == 0) { return $a; } $result = power_of_matrix([[$a+$b, $b], [$b, $a]], $n - 1); return $result[0][0]; } 的时间复杂度。为了最终达到线性时间以下,我们需要优化O(n)

现在,我们将矩阵乘以power_of_matrix()次。但我们真的必须这样做吗?让我们分解一个简单的等式:

n

通过计算2^8 = 256 = 2^4 * 2^4 = 2^4 * 2^2 * 2^2 = 2^4 * 2^2 * 2 * 2 '幂,我们可以存储结果并乘以它,为我们节省了很多乘法步骤。我们只需要确保,如果功率不均匀,我们将结果乘以一个额外的时间。

相同的逻辑适用于矩阵,我们可以使用它来优化n/2,如下所示:

power_of_matrix

现在解决方案的时间复杂度为function power_of_matrix(array $matr, $n) { if ($n == 0 || $n == 1) { return $matr; } $result = power_of_matrix($matr, intval($n/2)); $result = multiply_matrix($result, $result); if ($n % 2 != 0) { return multiply_matrix($result, $matr); } return $result; } 。但是,因为我们在这里使用递归,并且由于PHP数组的性质,此方法没有O(log n)空间复杂度。

为了实现这一点,我们必须通过引用传递矩阵并对其进行修改,而不是每次都返回一个新的结果矩阵。

我希望这有助于您理解和解决问题。