So concerning your code, you have achieved space complexity of O(1)
but your time complexity is still O(n)
, as it will still take n
executions of the for loop to find the n'th
number.
Secondly, the function you are trying to create can produce the fibonacci sequence, but can also produce other sequences using the same principle but starting from different numbers.
First thing we'll need to do to solve this problem in less than linear time, is to represent the sequence using matrices, like so:

We can create the matrix on the left from the two initial numbers. We can then raise it to the n-1
power, and we will get our desired number in the top left corner of the result matrix.
Simple implementation in PHP could look like this:
/**
* 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];
}
But, as you can probably see, we still haven't got rid of the for loop, meaning we still have a time complexity of O(n)
. To finally get below linear time, we'll need to optimise power_of_matrix()
.
Right now, we're multiplying the matrices n
times. But do we really have to do that ? Let's break down a simple equation:
2^8 = 256 = 2^4 * 2^4 = 2^4 * 2^2 * 2^2 = 2^4 * 2^2 * 2 * 2
By calculating the n/2
'th power, we can store the result and multiply by it, saving us a lot of multiplication steps. We just need to make sure that, if the power is not even, we multiply the result one extra time.
Same logic applies to matrices, and we can use it to optimise power_of_matrix
like so:
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;
}
Now the solution has a time complexity of O(log n)
. However, because we're using recursion here, and because of the nature of PHP arrays, this method doesn't have O(1)
space complexity.
In order to achieve that, we'd have to pass the matrix by reference and modify it, instead of returning a new result matrix each time.
I hope this helps you in understanding and solving the problem.