mirror of
https://github.com/onyx-and-iris/grokking-algorithms.git
synced 2025-01-18 00:30:53 +00:00
clean up repo.
add more notes
This commit is contained in:
parent
d552050f7e
commit
3fe14b8ac0
2
.gitignore
vendored
2
.gitignore
vendored
@ -160,3 +160,5 @@ cython_debug/
|
||||
#.idea/
|
||||
|
||||
words_alpha.txt
|
||||
|
||||
tests/
|
5
chapter1/README.md
Normal file
5
chapter1/README.md
Normal file
@ -0,0 +1,5 @@
|
||||
# Binary Search
|
||||
|
||||
Repeatedly split the array checking if value is greater or less than the mid point. Stop when the exact value is found.
|
||||
|
||||
It takes log N steps to reduce an array of size N to an array of size 1. Time complexity for this algorithm is `O(log N)`.
|
@ -30,11 +30,14 @@ SAMPLE_SIZE = 1000
|
||||
numbers = random.sample(range(LOWER, UPPER), SAMPLE_SIZE)
|
||||
numbers.sort()
|
||||
|
||||
seen = set()
|
||||
count = 0
|
||||
result = None
|
||||
while result is None:
|
||||
while not result:
|
||||
guess = random.randrange(LOWER, UPPER)
|
||||
logger.debug(f"guess: {guess}")
|
||||
result = binary_search(numbers, guess)
|
||||
if guess not in seen:
|
||||
count += 1
|
||||
seen.add(guess)
|
||||
result = binary_search(numbers, guess)
|
||||
|
||||
|
||||
print(f"Found {guess} at index {result}.")
|
||||
print(f"Found {guess} at index {result} after {count} attempts")
|
||||
|
@ -1,7 +0,0 @@
|
||||
import math
|
||||
|
||||
num_steps = int(math.log2(128))
|
||||
print(
|
||||
f"A binary search would take maximum {num_steps} steps "
|
||||
"to search a list of 128 items."
|
||||
)
|
@ -1,7 +0,0 @@
|
||||
import math
|
||||
|
||||
num_steps = int(math.log2(128*2))
|
||||
print(
|
||||
f"A binary search would take maximum {num_steps} steps "
|
||||
"to search a list of 256 items."
|
||||
)
|
7
chapter2/README.md
Normal file
7
chapter2/README.md
Normal file
@ -0,0 +1,7 @@
|
||||
# Selection Sort
|
||||
|
||||
We have to perform N swaps a total of N times. This takes N^N steps, therefore:
|
||||
|
||||
This algorithm has time complexity `O(N^2)`
|
||||
|
||||
Technically (`n – 1, n - 2 ... 2, 1` ~= N/2) swaps are performed but in BigO the constants are dropped.
|
12
chapter4/README.md
Normal file
12
chapter4/README.md
Normal file
@ -0,0 +1,12 @@
|
||||
# Recursion
|
||||
|
||||
Recursive functions must have both:
|
||||
|
||||
- one or more base cases
|
||||
- a recursive case
|
||||
|
||||
The base cases are required to ensure the recursion stops when meeting a condition
|
||||
|
||||
The recursive case adds functions onto the call stack and completes each one top down.
|
||||
|
||||
Note. Quicksort should be implemented using a random pivot to ensure average runtimes.
|
@ -32,10 +32,14 @@ SAMPLE_SIZE = 1000
|
||||
numbers = random.sample(range(LOWER, UPPER), SAMPLE_SIZE)
|
||||
numbers.sort()
|
||||
|
||||
seen = set()
|
||||
count = 0
|
||||
result = None
|
||||
while result is None:
|
||||
guess = random.randrange(LOWER, UPPER)
|
||||
logger.debug(f"guess: {guess}")
|
||||
result = binary_search(numbers, 0, len(numbers) - 1, guess)
|
||||
if guess not in seen:
|
||||
count += 1
|
||||
seen.add(guess)
|
||||
result = binary_search(numbers, 0, len(numbers) - 1, guess)
|
||||
|
||||
print(f"Found {guess} at index {result}.")
|
||||
print(f"Found {guess} at index {result} after {count} attempts.")
|
||||
|
9
chapter6/README.md
Normal file
9
chapter6/README.md
Normal file
@ -0,0 +1,9 @@
|
||||
# Breadth-First Search
|
||||
|
||||
Can tell you if there's a path between A and B and will find the shortest.
|
||||
|
||||
In these examples, 1st degree Mango sellers are found before 2nd degree, 2nd before 3rd and so on.
|
||||
|
||||
Visted nodes should be stored in a set to ensure no infinite loops.
|
||||
|
||||
Running time for BFS on a directed graph: `O(V + E`) where V = vertices, E = edges.
|
@ -2,4 +2,4 @@
|
||||
|
||||
- Dijkstra's algorithm works when all weights are non-negative
|
||||
- If there are negative weights use Bellman-Ford.
|
||||
- Priority queue + min heap is optimal when compared to a function that operates on a list.
|
||||
- The book demonstrates a function that operates on a list. Priority queue + min heap added for completeness.
|
||||
|
@ -1,10 +0,0 @@
|
||||
import heapq
|
||||
|
||||
customers = []
|
||||
heapq.heappush(customers, (2, "Harry"))
|
||||
heapq.heappush(customers, (3, "Charles"))
|
||||
heapq.heappush(customers, (1, "Riya"))
|
||||
heapq.heappush(customers, (4, "Stacy"))
|
||||
|
||||
while customers:
|
||||
print(heapq.heappop(customers))
|
@ -1,14 +0,0 @@
|
||||
customers = []
|
||||
customers.append((2, "Harry")) # no sort needed here because 1 item.
|
||||
customers.append((3, "Charles"))
|
||||
customers.sort(reverse=True)
|
||||
# Need to sort to maintain order
|
||||
customers.append((1, "Riya"))
|
||||
customers.sort(reverse=True)
|
||||
# Need to sort to maintain order
|
||||
customers.append((4, "Stacy"))
|
||||
customers.sort(reverse=True)
|
||||
|
||||
while customers:
|
||||
print(customers.pop(0))
|
||||
# Will print names in the order: Stacy, Charles, Harry, Riya.
|
@ -1,12 +0,0 @@
|
||||
from queue import PriorityQueue
|
||||
|
||||
customers = (
|
||||
PriorityQueue()
|
||||
) # we initialise the PQ class instead of using a function to operate upon a list.
|
||||
customers.put((2, "Harry"))
|
||||
customers.put((3, "Charles"))
|
||||
customers.put((1, "Riya"))
|
||||
customers.put((4, "Stacy"))
|
||||
|
||||
while customers:
|
||||
print(customers.get())
|
Loading…
Reference in New Issue
Block a user