Skip to content

Commit

Permalink
Update complexity notation in graph.md and add dynamic programming ex…
Browse files Browse the repository at this point in the history
…ample in 05-dynamic-programming.md
  • Loading branch information
romarowski committed Feb 18, 2024
1 parent 960d70d commit 7f1de97
Show file tree
Hide file tree
Showing 5 changed files with 171 additions and 2 deletions.
4 changes: 2 additions & 2 deletions 04-graph.md
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,6 @@ b --> c
5. Finally, return the maximum distance found.

**Complexity**:
- Time: O(E) where E is the number of edges in the graph.
- Space: O(N) where N is the number of nodes in the graph.
- Time: $O(E)$ where $E$ is the number of edges in the graph.
- Space: $O(N)$ where $N$ is the number of nodes in the graph.

34 changes: 34 additions & 0 deletions 05-dynamic-programming.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,36 @@
## Dynamic Programming

### Fibonacci sequence problem

**Statement:** Given a number ```n``` $\in\N$, find the its Fibonacci number.

$$
\begin{align*}
F_0 &= 0, \\
F_1 &= 1, \\
F_n &= F_{n-1} + F_{n-2}
\end{align*}
$$

**Approach**:
It is possible to solve this problem with brute force recursion.

```python
def fib(n):
if n == 0:
return 0
if n == 1:
return 1
return fib(n-1) + fib(n-2)
```

Nevertheless this leads to repeated work. For example, the call to ```fib(3)``` will call ```fib(2)``` and ```fib(1)```, and the call to ```fib(2)``` will call ```fib(1)``` and ```fib(0)```. This means that the call to ```fib(1)``` is repeated.
Leading to a complexity of $O(2^n)$.

A better approach is to use **dynamic programming** and store the results of the subproblems.

**Complexity**:
- Time: $O(n)$
- Space: $O(n)$


32 changes: 32 additions & 0 deletions dynamic_programming/fib.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
"""
fib
Write a function fib that takes in a number argument, n, and returns
the n-th number of the Fibonacci sequence.
The 0-th number of the sequence is 0.
The 1-st number of the sequence is 1.
To generate further numbers of the sequence, calculate the sum of
previous two numbers.
Solve this recursively.
"""

def fib(n):
calculated = dict()
calculated[0] = 0
calculated[1] = 1
return _fib(n, calculated)


def _fib(n, calculated):

if n in calculated:
return calculated[n]

calculated[n] = _fib(n-1, calculated) + _fib(n-2, calculated)
return calculated[n]


print(fib(35)) # -> 9227465
70 changes: 70 additions & 0 deletions dynamic_programming/sum_possible.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
"""
sum possible
Write a function sum_possible that takes in an amount and a list of
positive numbers. The function should return a boolean indicating whether
or not it is possible to create the amount by summing numbers of the list.
You may reuse numbers of the list as many times as necessary.
You may assume that the target amount is non-negative.
"""

def sum_possible(amount, numbers):
for n in numbers:
possible = recur(amount, n, numbers)
if possible:
return True

return False

def recur(remainder, subtrahend, numbers):

if subtrahend > remainder:
return

remainder = remainder - subtrahend

if remainder == 0:
return True



return False






print(sum_possible(4, [1, 2, 3,])) # -> True, 4 + 4

###############################
# solution with n! complexity #
###############################

#def sum_possible(amount, numbers):
# for j in range(len(numbers)):
# possible =_mod(amount, numbers.copy(), j)
# if possible:
# return True
# return False
#
#def _mod(amount, numbers, i):
# # i need a way to keep track of the numbers i already used for that
# # branch of the recursive call
#
# # i need to try modding simultaneously with all values in the array
# if i == len(numbers):
# return
#
# #n = numbers[i]
# n = numbers.pop(i)
#
# if n > amount:
# return
#
# remainder = amount % n
# if remainder == 0:
# return True
#
# return _mod(remainder, numbers, 0)

33 changes: 33 additions & 0 deletions dynamic_programming/tribonacci.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
"""
tribonacci
Write a function tribonacci that takes in a number argument, n, and
returns the n-th number of the Tribonacci sequence.
The 0-th and 1-st numbers of the sequence are both 0.
The 2-nd number of the sequence is 1.
To generate further numbers of the sequence, calculate the sum of
previous three numbers.
Solve this recursively.
"""

def tribonacci(n):
memo = dict()
return _trib(n, memo)


def _trib(n, memo):
if n == 0 or n==1:
return 0
if n ==2:
return 1

if n in memo:
return memo[n]

memo[n] = _trib(n-1, memo) + _trib(n-2, memo) + _trib(n-3, memo)
return memo[n]

print(tribonacci(20)) # -> 35890

0 comments on commit 7f1de97

Please sign in to comment.