📋 Algorithm Templates - Quick Reference
Ready-to-use algorithm implementations and patterns
Standard templates for common algorithmic problems
🔍 Search Algorithms
Binary Search
def binary_search(arr, target):
left, right = 0, len(arr) - 1
while left <= right:
mid = (left + right) // 2
if arr[mid] == target:
return mid
elif arr[mid] < target:
left = mid + 1
else:
right = mid - 1
return -1 # Not found
# Recursive version
def binary_search_recursive(arr, target, left=0, right=None):
if right is None:
right = len(arr) - 1
if left > right:
return -1
mid = (left + right) // 2
if arr[mid] == target:
return mid
elif arr[mid] < target:
return binary_search_recursive(arr, target, mid + 1, right)
else:
return binary_search_recursive(arr, target, left, mid - 1)
Linear Search
def linear_search(arr, target):
for i in range(len(arr)):
if arr[i] == target:
return i
return -1
# With early termination for sorted arrays
def linear_search_sorted(arr, target):
for i in range(len(arr)):
if arr[i] == target:
return i
elif arr[i] > target:
break
return -1
🔄 Sorting Algorithms
Quick Sort
def quick_sort(arr, low=0, high=None):
if high is None:
high = len(arr) - 1
if low < high:
pivot_index = partition(arr, low, high)
quick_sort(arr, low, pivot_index - 1)
quick_sort(arr, pivot_index + 1, high)
def partition(arr, low, high):
pivot = arr[high]
i = low - 1
for j in range(low, high):
if arr[j] <= pivot:
i += 1
arr[i], arr[j] = arr[j], arr[i]
arr[i + 1], arr[high] = arr[high], arr[i + 1]
return i + 1
Merge Sort
def merge_sort(arr):
if len(arr) <= 1:
return arr
mid = len(arr) // 2
left = merge_sort(arr[:mid])
right = merge_sort(arr[mid:])
return merge(left, right)
def merge(left, right):
result = []
i = j = 0
while i < len(left) and j < len(right):
if left[i] <= right[j]:
result.append(left[i])
i += 1
else:
result.append(right[j])
j += 1
result.extend(left[i:])
result.extend(right[j:])
return result
Insertion Sort
def insertion_sort(arr):
for i in range(1, len(arr)):
key = arr[i]
j = i - 1
while j >= 0 and arr[j] > key:
arr[j + 1] = arr[j]
j -= 1
arr[j + 1] = key
return arr
Selection Sort
def selection_sort(arr):
n = len(arr)
for i in range(n - 1):
min_idx = i
for j in range(i + 1, n):
if arr[j] < arr[min_idx]:
min_idx = j
arr[i], arr[min_idx] = arr[min_idx], arr[i]
return arr
🕸️ Graph Algorithms
Depth-First Search (DFS)
# Recursive DFS
def dfs_recursive(graph, vertex, visited=None):
if visited is None:
visited = set()
visited.add(vertex)
print(vertex, end=' ')
for neighbor in graph[vertex]:
if neighbor not in visited:
dfs_recursive(graph, neighbor, visited)
# Iterative DFS
def dfs_iterative(graph, start):
visited = set()
stack = [start]
while stack:
vertex = stack.pop()
if vertex not in visited:
visited.add(vertex)
print(vertex, end=' ')
# Add neighbors in reverse order for same traversal as recursive
for neighbor in reversed(graph[vertex]):
if neighbor not in visited:
stack.append(neighbor)
Breadth-First Search (BFS)
from collections import deque
def bfs(graph, start):
visited = set([start])
queue = deque([start])
while queue:
vertex = queue.popleft()
print(vertex, end=' ')
for neighbor in graph[vertex]:
if neighbor not in visited:
visited.add(neighbor)
queue.append(neighbor)
# BFS with distance tracking
def bfs_with_distance(graph, start):
visited = {start: 0}
queue = deque([start])
while queue:
vertex = queue.popleft()
for neighbor in graph[vertex]:
if neighbor not in visited:
visited[neighbor] = visited[vertex] + 1
queue.append(neighbor)
return visited
🌲 Tree Algorithms
Binary Tree Traversals
class TreeNode:
def __init__(self, val=0, left=None, right=None):
self.val = val
self.left = left
self.right = right
# Inorder Traversal (Left, Root, Right)
def inorder_traversal(root):
result = []
if root:
result.extend(inorder_traversal(root.left))
result.append(root.val)
result.extend(inorder_traversal(root.right))
return result
# Preorder Traversal (Root, Left, Right)
def preorder_traversal(root):
result = []
if root:
result.append(root.val)
result.extend(preorder_traversal(root.left))
result.extend(preorder_traversal(root.right))
return result
# Postorder Traversal (Left, Right, Root)
def postorder_traversal(root):
result = []
if root:
result.extend(postorder_traversal(root.left))
result.extend(postorder_traversal(root.right))
result.append(root.val)
return result
# Level Order Traversal (BFS)
def level_order_traversal(root):
if not root:
return []
result = []
queue = deque([root])
while queue:
node = queue.popleft()
result.append(node.val)
if node.left:
queue.append(node.left)
if node.right:
queue.append(node.right)
return result
Binary Search Tree Operations
class BST:
def __init__(self):
self.root = None
def insert(self, val):
self.root = self._insert_recursive(self.root, val)
def _insert_recursive(self, node, val):
if not node:
return TreeNode(val)
if val < node.val:
node.left = self._insert_recursive(node.left, val)
elif val > node.val:
node.right = self._insert_recursive(node.right, val)
return node
def search(self, val):
return self._search_recursive(self.root, val)
def _search_recursive(self, node, val):
if not node or node.val == val:
return node
if val < node.val:
return self._search_recursive(node.left, val)
else:
return self._search_recursive(node.right, val)
def delete(self, val):
self.root = self._delete_recursive(self.root, val)
def _delete_recursive(self, node, val):
if not node:
return node
if val < node.val:
node.left = self._delete_recursive(node.left, val)
elif val > node.val:
node.right = self._delete_recursive(node.right, val)
else:
# Node to be deleted found
if not node.left:
return node.right
elif not node.right:
return node.left
# Node with two children
min_node = self._find_min(node.right)
node.val = min_node.val
node.right = self._delete_recursive(node.right, min_node.val)
return node
def _find_min(self, node):
while node.left:
node = node.left
return node
🔁 Recursive Patterns
Fibonacci (Optimized)
# Memoized version
def fibonacci_memo(n, memo={}):
if n in memo:
return memo[n]
if n <= 1:
return n
memo[n] = fibonacci_memo(n-1, memo) + fibonacci_memo(n-2, memo)
return memo[n]
# Iterative version
def fibonacci_iterative(n):
if n <= 1:
return n
a, b = 0, 1
for _ in range(2, n + 1):
a, b = b, a + b
return b
Tower of Hanoi
def hanoi(n, source, destination, auxiliary):
if n == 1:
print(f"Move disk 1 from {source} to {destination}")
return 1
moves = 0
moves += hanoi(n-1, source, auxiliary, destination)
print(f"Move disk {n} from {source} to {destination}")
moves += 1
moves += hanoi(n-1, auxiliary, destination, source)
return moves
Power Function
# Fast exponentiation
def power(base, exp):
if exp == 0:
return 1
elif exp % 2 == 0:
half_power = power(base, exp // 2)
return half_power * half_power
else:
return base * power(base, exp - 1)
🏗️ Data Structure Templates
Stack Implementation
class Stack:
def __init__(self):
self.items = []
def push(self, item):
self.items.append(item)
def pop(self):
if self.is_empty():
raise IndexError("Stack is empty")
return self.items.pop()
def peek(self):
if self.is_empty():
raise IndexError("Stack is empty")
return self.items[-1]
def is_empty(self):
return len(self.items) == 0
def size(self):
return len(self.items)
Queue Implementation
from collections import deque
class Queue:
def __init__(self):
self.items = deque()
def enqueue(self, item):
self.items.append(item)
def dequeue(self):
if self.is_empty():
raise IndexError("Queue is empty")
return self.items.popleft()
def front(self):
if self.is_empty():
raise IndexError("Queue is empty")
return self.items[0]
def is_empty(self):
return len(self.items) == 0
def size(self):
return len(self.items)
Linked List Implementation
class ListNode:
def __init__(self, val=0, next=None):
self.val = val
self.next = next
class LinkedList:
def __init__(self):
self.head = None
self.size = 0
def insert_at_head(self, val):
new_node = ListNode(val)
new_node.next = self.head
self.head = new_node
self.size += 1
def insert_at_tail(self, val):
new_node = ListNode(val)
if not self.head:
self.head = new_node
else:
current = self.head
while current.next:
current = current.next
current.next = new_node
self.size += 1
def delete(self, val):
if not self.head:
return False
if self.head.val == val:
self.head = self.head.next
self.size -= 1
return True
current = self.head
while current.next and current.next.val != val:
current = current.next
if current.next:
current.next = current.next.next
self.size -= 1
return True
return False
def search(self, val):
current = self.head
index = 0
while current:
if current.val == val:
return index
current = current.next
index += 1
return -1
🎯 Problem-Solving Patterns
Two Pointers
def two_sum_sorted(arr, target):
left, right = 0, len(arr) - 1
while left < right:
current_sum = arr[left] + arr[right]
if current_sum == target:
return [left, right]
elif current_sum < target:
left += 1
else:
right -= 1
return []
Sliding Window
def max_sum_subarray(arr, k):
if len(arr) < k:
return None
# Calculate sum of first window
window_sum = sum(arr[:k])
max_sum = window_sum
# Slide the window
for i in range(k, len(arr)):
window_sum = window_sum - arr[i - k] + arr[i]
max_sum = max(max_sum, window_sum)
return max_sum
Backtracking Template
def backtrack_template(candidates, path, result, target):
# Base case
if is_valid_solution(path, target):
result.append(path[:]) # Make a copy
return
# Try all possible candidates
for candidate in candidates:
if is_valid_candidate(candidate, path):
# Make choice
path.append(candidate)
# Recurse
backtrack_template(get_next_candidates(candidates, candidate),
path, result, target)
# Backtrack
path.pop()
🧮 Mathematical Algorithms
GCD (Euclidean Algorithm)
def gcd(a, b):
while b:
a, b = b, a % b
return a
# Recursive version
def gcd_recursive(a, b):
if b == 0:
return a
return gcd_recursive(b, a % b)
Prime Number Checking
def is_prime(n):
if n < 2:
return False
if n == 2:
return True
if n % 2 == 0:
return False
for i in range(3, int(n**0.5) + 1, 2):
if n % i == 0:
return False
return True
Sieve of Eratosthenes
def sieve_of_eratosthenes(n):
is_prime = [True] * (n + 1)
is_prime[0] = is_prime[1] = False
for i in range(2, int(n**0.5) + 1):
if is_prime[i]:
for j in range(i*i, n + 1, i):
is_prime[j] = False
return [i for i in range(2, n + 1) if is_prime[i]]
🧭 Navigation
Hub: 🏠 Algorithms Knowledge Hub
Study Materials: Study Material/
Quick Reference: ⚡ Algorithm Quick Reference
Algorithm Templates | Implementation Reference | Updated: 2025-08-25