![]() |
VOOZH | about |
Given an integer N, the task is to find the N-th Fibonacci numbers.
Examples:
Input: N = 3
Output: 2
Explanation:
F(1) = 1, F(2) = 1
F(3) = F(1) + F(2) = 2
Input: N = 6
Output: 8
Approach:
F(n+1) = F(n) + F(n-1)
F(2n) = F(n)[2F(n+1) – F(n)]
F(2n + 1) = F(n)2+F(n+1)2
Start with:
F(n+1) = F(n) + F(n-1) &
F(n) = F(n)
It can be rewritten in the matrix form as:
For doubling, we just plug in "2n" into the formula:
Substituting F(n-1) = F(n+1)- F(n) and after simplification we get,
Below is the implementation of the above approach:
8
Time Complexity: Repeated squaring reduces time from linear to logarithmic . Hence, with constant time arithmetic, the time complexity is O(log n).
Auxiliary Space: O(n).
Iterative Version
We can implement iterative version of above method, by initializing array with two elements f = [F(0), F(1)] = [0, 1] and iteratively constructing F(n), on every step we will transform f into [F(2i), F(2i+1)] or [F(2i+1), F(2i+2)] , where i corresponds to the current value of i stored in f = [F(i), F(i+1)].
Approach:
if bk == 0:
f = [F(2i), F(2i+1)] = [F(i){2F(i+1)-F(i)}, F(i+1)2+F(i)2]
if bk == 1:
f = [F(2i+1), F(2i+2)] = [F(i+1)2+F(i)2, F(i+1){2F(i)+F(i+1)}]
where,
F(i) and F(i+1) are current values stored in f.
Example:
for n = 13 = (1101)2
b = 1 1 0 1
[F(0), F(1)] -> [F(1), F(2)] -> [F(3), F(4)] -> [F(6), F(7)] -> [F(13), F(14)]
[0, 1] -> [1, 1] -> [2, 3] -> [8, 13] -> [233, 377]
Below is the implementation of the above approach:
F(13) = 233
Time Complexity: We are iterating over a binary string of length n and doing constant time arithmetic operations for each digit, so the time complexity is O(n).
Auxiliary Space: We are storing two elements in f (which is a constant cost), and the binary representation of the number (which has a cost of O(n)) so space complexity is O(n). We could reduce this down to O(1) if we didn't convert the number to a string, but instead used the bits of the number to iterate through .