Loading repository dataβ¦
Loading repository dataβ¦
wesleyscholl / repository
π¨π»βπ»ππ‘ A comprehensive Algorithm Code Patterns & Complexity Study Guide for interviews. This is designed to be both a cheat sheet π and a mini reference book π, with concise explanations, sample code π», and complexity tables π β ideal for DevOps βοΈ, AI/ML π§ , or software engineering interview prep π
Status: Comprehensive technical interview preparation resource with 700+ implementations - actively maintained study guide for algorithm mastery.
A comprehensive repository to help you master algorithm patterns, build intuition, and ace technical interviews.
Includes pattern reference guide, Python implementations, tests, and study resources.
# Clone the repository
git clone https://github.com/yourusername/algos.git
cd algos
# Run setup script
chmod +x setup.sh
./setup.sh
# Or manually:
python3 -m venv venv
source venv/bin/activate
pip install -r requirements.txt
pytest tests/
algos/
βββ implementations/ # Algorithm implementations by pattern
β βββ hash_map.py # O(1) lookups, counting
β βββ two_pointers.py # Sorted arrays, palindromes
β βββ sliding_window.py # Substrings, subarrays
β βββ binary_search.py # Search, optimization
β βββ dfs_backtracking.py # All possibilities
β βββ bfs.py # Level-order, shortest paths
β βββ dynamic_programming.py # Optimal substructure
β βββ graphs.py # DFS, BFS, Union-Find, Dijkstra
β βββ heaps.py # Priority queues, top-k
βββ tests/ # Comprehensive test suite
βββ examples.py # Runnable examples
βββ README.md # This file (pattern cheat sheet)
βββ CONTRIBUTING.md # Contribution guidelines
βββ STUDY_GUIDE.md # Structured study plan
βββ requirements.txt # Dependencies
β
100+ Algorithm Implementations - Production-ready code with tests
β
Comprehensive Documentation - Docstrings with complexity analysis
β
Full Test Coverage - Pytest suite with edge cases
β
Pattern-Based Organization - Learn by algorithm patterns
β
Study Guide - 8-week structured learning plan
β
Examples - Runnable demonstrations of each pattern
# All tests
pytest tests/
# Specific pattern
pytest tests/test_hash_map.py
# With coverage
pytest --cov=implementations tests/
# Verbose output
pytest -v tests/
# Run doctests
python -m doctest implementations/hash_map.py
from implementations.hash_map import two_sum
from implementations.sliding_window import length_of_longest_substring
from implementations.graphs import UnionFind
# Hash Map Pattern
result = two_sum([2, 7, 11, 15], 9)
print(result) # [0, 1]
# Sliding Window Pattern
length = length_of_longest_substring("abcabcbb")
print(length) # 3
# Graph Pattern
uf = UnionFind(5)
uf.union(0, 1)
print(uf.connected(0, 1)) # True
Or run all examples:
python examples.py
implementations/python examples.py to see patterns in actiontests/Pattern: Fast lookups, counting, and complements.
When to Use: When you need O(1) access to previously seen data.
Examples:
# Two Sum
d = {}
for i, n in enumerate(nums):
if target - n in d:
return [d[target - n], i]
d[n] = i
Common Variants:
Counter(nums)Complexity:
| Operation | Time | Space |
|---|---|---|
| Insert / Lookup | O(1) | O(n) |
Pattern: Use two indices moving inward or outward. When to Use: Sorted arrays, linked lists, or string comparisons.
Examples:
l, r = 0, len(nums) - 1
while l < r:
s = nums[l] + nums[r]
if s == target: return [l, r]
if s < target: l += 1
else: r -= 1
Variations:
Complexity:
| Operation | Time | Space |
|---|---|---|
| Traverse once | O(n) | O(1) |
Pattern: Dynamic window that expands/contracts. When to Use: Substrings, subarrays, or fixed-size segment problems.
Examples:
window, l, best = {}, 0, 0
for r, c in enumerate(s):
window[c] = window.get(c, 0) + 1
while window[c] > 1:
window[s[l]] -= 1
l += 1
best = max(best, r - l + 1)
Types:
Complexity:
| Operation | Time | Space |
|---|---|---|
| Move window | O(n) | O(k) |
Pattern: Store cumulative results to answer range queries fast. When to Use: Subarray sums, range differences, balance tracking.
Examples:
prefix = {0: 1}
s = res = 0
for n in nums:
s += n
res += prefix.get(s - k, 0)
prefix[s] = prefix.get(s, 0) + 1
Complexity:
| Operation | Time | Space |
|---|---|---|
| Build prefix | O(n) | O(n) |
Pattern: Divide and conquer to find an element or condition boundary. When to Use: Sorted data, search conditions, or monotonic functions.
Examples:
l, r = 0, len(nums) - 1
while l <= r:
m = (l + r) // 2
if nums[m] == target: return m
if nums[m] < target: l = m + 1
else: r = m - 1
Binary Search on Answer: Used for optimization problems (βminimum X such thatβ¦β).
Complexity:
| Operation | Time | Space |
|---|---|---|
| Search | O(log n) | O(1) |
Pattern: Explore all possibilities (tree, grid, graph, recursion). When to Use: All subsets, permutations, paths, or decision trees.
Examples:
def dfs(i, path):
if i == len(nums):
res.append(path[:])
return
dfs(i + 1, path + [nums[i]])
dfs(i + 1, path)
Backtracking Tip: Undo changes before returning from recursion.
Complexity:
| Operation | Time | Space |
|---|---|---|
| Explore all | O(2βΏ) | O(n) |
Pattern: Level-by-level traversal using a queue. When to Use: Shortest path, level order, connected components.
Examples:
from collections import deque
q = deque([start])
seen = {start}
while q:
node = q.popleft()
for nei in graph[node]:
if nei not in seen:
seen.add(nei)
q.append(nei)
Complexity:
| Operation | Time | Space |
|---|---|---|
| Visit all | O(V + E) | O(V) |
Pattern: Break problem into overlapping subproblems. When to Use: Optimal decisions, counting, or sequences.
Examples:
dp = [0] * (n + 1)
dp[0], dp[1] = 0, 1
for i in range(2, n + 1):
dp[i] = dp[i-1] + dp[i-2]
Tips:
Complexity:
| Operation | Time | Space |
|---|---|---|
| DP solution | O(n) | O(n) (β O(1) optimized) |
Pattern: Always choose best local decision hoping for global optimum. When to Use: Scheduling, intervals, simple optimization.
Examples:
intervals.sort(key=lambda x: x[1])
end, count = float('-inf'), 0
for s, e in intervals:
if s >= end:
count += 1
end = e
Complexity:
| Operation | Time | Space |
|---|---|---|
| Sort + Iterate | O(n log n) | O(1) |
Common Uses:
nums.sort()
| Algorithm | Average | Worst | Space | Stable |
|---|---|---|---|---|
| QuickSort | O(n log n) | O(nΒ²) | O(log n) | β |
| MergeSort | O(n log n) | O(n log n) | O(n) | β |
| HeapSort | O(n log n) | O(n log n) | O(1) | β |
TimSort (Python sort()) | O(n log n) | O(n log n) | O(n) | β |
Pattern: Extract min/max efficiently. When to Use: Top-k problems, running median, Dijkstraβs.
Examples:
import heapq
heap = []
for x in nums:
heapq.heappush(heap, x)
if len(heap) > k: heapq.heappop(heap)
Complexity:
| Operation | Time | Space |
|---|---|---|
| Push/Pop | O(log n) | O(n) |
Representation:
graph = {u: [] for u in range(n)}
for u, v in edges:
graph[u].append(v)
Traversals:
Complexity:
| Operation | Time | Space |
|---|---|---|
| DFS/BFS | O(V + E) | O(V + E) |
| Union-Find | O(Ξ±(n)) per op | O(n) |
| Operation / Pattern | Time Complexity | Space |
|---|---|---|
| Single Loop | O(n) | O(1) |
| Nested Loops | O(nΒ²) | O(1) |
| Sorting | O(n log n) | O(1) |
| Binary Search | O(log n) | O(1) |
| DFS / BFS | O(V + E) | O(V) |
| Dynamic Programming | O(n) β O(nΒ²) | O(n) |
| Backtracking | O(2βΏ) | O(n) |
| Matrix Traversal | O(m Γ n) | O(1) |
Operations as input size (n) grows:
O(