Fibonacci
Brute force
def fib_brute_force(n) -> int:
"""
Time complexity: O(2^N)
It's a recursive function, with a branching factor of 2.
This means, until arriving to N it performs two calls.
Space complexity: O(N)
In recursive functions, we need to have into account the stack space
needed for every call. In this case, it will grow depending on N.
"""
if n <= 2:
return 1
else:
return fib(n-1) + fib(n-2)
Memoization
def fib_dynamic(n, index = None) -> int:
"""
Time complexity: O(N)
With this approach, we won't make a recursive call if we already passed
by that value. So, worst case scenario we will go over N iterations.
Space complexity: O(N)
For the same reasons, the stack space will depend on N.
"""
if index is None:
index = {}
if n in index.keys():
return index[n]
if n <= 2:
return 1
else:
index[n] = fib(n-1, index) + fib(n-2, index)
return index[n]
Tabulation
def fib_dynamic_tab(n: int) -> int:
"""
Time complexity: O(N)
It only interates the array once
Space complexity: O(N)
It only requires an array of size N + 1
"""
table = [0] * (n + 1)
table[1] = 1
for i in range(len(table)):
if (i + 1) < len(table):
table[i + 1] += table[i]
if (i + 2) < len(table):
table[i + 2] += table[i]
return table[-1]
Last updated