寻找复杂性代码为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);
}
原始问题是
答案 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)
空间复杂度。
为了实现这一点,我们必须通过引用传递矩阵并对其进行修改,而不是每次都返回一个新的结果矩阵。
我希望这有助于您理解和解决问题。