Two Pointers
Two coordinated indexes replace a nested loop on sorted or partitionable data.
When to identify it
- Sorted array + pair/triplet target
- 'In place' / 'O(1) space' filtering
- Comparing elements from both ends
Visual clues in the prompt
- “A sorted input”
- “'find two/three that sum to…'”
- “'remove/move/partition in place'”
Template
1left, right = 0, len(nums) - 12while left < right:3 total = nums[left] + nums[right]4 if total == target: return [left, right]5 if total < target: left += 16 else: right -= 1
Common variations
- Converging (pair sum)
- Read/write (move zeroes)
- Fast/slow (cycle detection)
Sliding Window
Maintain a contiguous window with incrementally-updated state instead of recomputing each subarray.
When to identify it
- 'Longest/shortest/count' + 'contiguous/substring/subarray'
- Window-checkable constraint
- Fixed size k given
Visual clues in the prompt
- “'longest substring such that…'”
- “'maximum sum of k consecutive'”
- “'smallest window containing…'”
Template
1left = 02for right in range(len(s)):3 add(s[right])4 while invalid():5 remove(s[left]); left += 16 best = max(best, right - left + 1)
Common variations
- Fixed size
- Variable (expand/contract while broken)
- Shrink while valid (minimum window)
Fast & Slow Pointers
Two pointers at different speeds detect cycles and find midpoints in one pass.
When to identify it
- Linked list cycle questions
- 'Find the middle'
- 'kth from the end'
Visual clues in the prompt
- “'does the list have a cycle?'”
- “'find where the cycle begins'”
- “'happy number'”
Template
1slow = fast = head2while fast and fast.next:3 slow = slow.next4 fast = fast.next.next5 if slow is fast: return True
Common variations
- Cycle detection
- Cycle entry (Floyd part 2)
- Midpoint / kth-from-end
Prefix Sum
Precompute cumulative totals once; answer any range sum in O(1).
When to identify it
- Many range-sum queries on static data
- 'count subarrays with sum k'
- Range updates then read
Visual clues in the prompt
- “'sum of elements from i to j'”
- “'subarray sums equal to…'”
- “'immutable range query'”
Template
1prefix = [0]2for x in nums: prefix.append(prefix[-1] + x)3
Common variations
- Range-sum query
- Prefix + hash map (sum = k)
- Difference array
- 2-D prefix
Binary Search
Halve a sorted (or monotonic) search space each probe.
When to identify it
- Sorted array lookup
- 'minimum/maximum value such that…'
- Monotonic feasibility test
Visual clues in the prompt
- “Sorted input”
- “'find the first/last…'”
- “'minimum capacity/speed/days to…'”
Template
1lo, hi = 0, len(a)2while lo < hi:3 mid = (lo + hi) // 24 if feasible(mid): hi = mid5 else: lo = mid + 16return lo
Common variations
- Classic lookup
- Lower/upper bound
- Rotated array
- Binary search on the answer
Merge Intervals
Sort by start, then sweep, merging or comparing overlapping ranges.
When to identify it
- Input is intervals [start, end]
- 'merge/insert/count overlaps'
- Scheduling/booking
Visual clues in the prompt
- “'merge overlapping intervals'”
- “'minimum meeting rooms'”
- “'can attend all meetings'”
Template
1intervals.sort(key=lambda iv: iv[0])2for start, end in intervals:3 if merged and start <= merged[-1][1]:4 merged[-1][1] = max(merged[-1][1], end)5 else:6 merged.append([start, end])
Common variations
- Merge
- Insert interval
- Non-overlapping (greedy by end)
- Meeting rooms (heap of ends)
Monotonic Stack
A stack kept sorted by evicting violators answers next-greater/smaller in one pass.
When to identify it
- 'next/previous greater/smaller element'
- Histogram / rectangle area
- Span / temperature-to-warmer
Visual clues in the prompt
- “'days until warmer temperature'”
- “'largest rectangle'”
- “'next greater element'”
Template
1stack = [] 2for i, x in enumerate(nums):3 while stack and nums[stack[-1]] < x:4 ans[stack.pop()] = x5 stack.append(i)
Common variations
- Next greater/smaller
- Largest rectangle
- Trapping rain water
- Remove k digits
Top-K Elements (Heap)
A size-k heap keeps the best k seen so far in O(n log k).
When to identify it
- 'k largest/smallest/most frequent'
- 'kth largest'
- Streaming best-of
Visual clues in the prompt
- “'top k frequent'”
- “'kth largest element'”
- “'k closest points'”
Template
1import heapq2heap = []3for x in nums:4 heapq.heappush(heap, x)5 if len(heap) > k: heapq.heappop(heap)6return heap
Common variations
- Kth largest
- Top-k frequent
- K closest points
- Merge k sorted lists
K-Way Merge
A heap of the current front of each sorted source merges them in O(N log k).
When to identify it
- Merging k sorted lists/arrays
- 'smallest range covering all lists'
- Matrix with sorted rows
Visual clues in the prompt
- “'merge k sorted…'”
- “'kth smallest in sorted matrix'”
- “'smallest range'”
Template
1heap = [(lst[0], i, 0) for i, lst in enumerate(lists) if lst]2heapq.heapify(heap)3while heap:4 val, i, j = heapq.heappop(heap)5 out.append(val)6 if j + 1 < len(lists[i]):7 heapq.heappush(heap, (lists[i][j+1], i, j+1))
Common variations
- Merge k lists
- Kth smallest in sorted matrix
- Smallest range
Breadth-First Search
A queue explores by distance layers — shortest paths in unweighted graphs.
When to identify it
- 'shortest/minimum steps'
- Level-order tree traversal
- Grid/maze reachability
Visual clues in the prompt
- “'fewest moves to…'”
- “'level order'”
- “'rotting oranges' / 'walls and gates'”
Template
1queue = deque([start]); seen = {start}2while queue:3 node = queue.popleft()4 for nb in neighbors(node):5 if nb not in seen:6 seen.add(nb); queue.append(nb)
Common variations
- Tree level order
- Grid/multi-source BFS
- Word ladder (implicit graph)
- 0-1 BFS (deque)
Depth-First Search
Dive deep then backtrack — components, cycles, and orderings.
When to identify it
- Connected components / islands
- Cycle detection
- Path enumeration / tree recursion
Visual clues in the prompt
- “'number of islands'”
- “'all paths from source to target'”
- “'detect a cycle'”
Template
1def dfs(node):2 visited.add(node)3 for nb in neighbors(node):4 if nb not in visited:5 dfs(nb)
Common variations
- Recursive/iterative
- Grid flood fill
- Cycle detection (3-color)
- Path sum
Topological Sort
Order a DAG so every edge points forward — peel zero-indegree nodes.
When to identify it
- Dependencies / prerequisites / build order
- 'can you finish all…'
- Directed acyclic ordering
Visual clues in the prompt
- “'course schedule'”
- “'build order'”
- “'alien dictionary'”
Template
1queue = deque(n for n in graph if indeg[n] == 0)2while queue:3 node = queue.popleft(); order.append(node)4 for nb in graph[node]:5 indeg[nb] -= 16 if indeg[nb] == 0: queue.append(nb)7
Common variations
- Kahn's (BFS indegree)
- DFS post-order
- Cycle detection
- Lexicographically smallest
Union-Find
Merge groups and query connectivity in near-O(1) as edges arrive.
When to identify it
- Dynamic connectivity (streamed edges)
- 'number of groups/provinces'
- Redundant connection / cycle
Visual clues in the prompt
- “'accounts merge'”
- “'number of connected components'”
- “'redundant edge'”
Template
1def find(x):2 while parent[x] != x:3 parent[x] = parent[parent[x]]; x = parent[x]4 return x5def union(a, b):6 parent[find(a)] = find(b)
Common variations
- Path compression + rank
- Cycle detection
- Component counting
- Kruskal's MST
Backtracking
Choose, explore, un-choose — systematic search of a decision tree with pruning.
When to identify it
- 'all subsets/permutations/combinations'
- Constraint puzzles (N-Queens, Sudoku)
- 'generate all valid…'
Visual clues in the prompt
- “'find all…'”
- “'generate parentheses'”
- “'word search' / 'partition'”
Template
1def bt(state):2 if complete(state): record(state); return3 for choice in choices(state):4 make(choice); bt(state); undo(choice)
Common variations
- Subsets/permutations/combinations
- Constraint pruning (N-Queens)
- Grid search
Dynamic Programming
Reuse overlapping-subproblem answers; define state, write transition.
When to identify it
- 'count the ways' / 'min/max cost'
- Overlapping subproblems in recursion
- Choices with optimal substructure
Visual clues in the prompt
- “'how many ways to…'”
- “'minimum cost to…'”
- “'longest/edit/knapsack'”
Template
1dp = [base] * (n + 1)2for i in range(1, n + 1):3 dp[i] = transition(dp[i-1], dp[i-2], ...)4return dp[n]
Common variations
- 1-D (stairs, robber)
- Knapsack
- String DP (LCS, edit)
- Grid DP
- Bitmask DP
Greedy
Commit to the locally optimal choice when it provably stays globally optimal.
When to identify it
- 'maximum/minimum number of…'
- Interval scheduling
- Provable greedy-choice property
Visual clues in the prompt
- “'maximum meetings'”
- “'minimum arrows/platforms'”
- “'jump game'”
Template
1items.sort(key=chosen_key)2for item in items:3 if compatible(item, state):4 take(item); update(state)
Common variations
- Interval scheduling
- Jump/reachability
- Huffman
- Fractional knapsack
Cyclic Sort
When values are 1..n, place each at its home index to find missing/duplicate in O(n)/O(1).
When to identify it
- Array of n values in range 1..n
- 'find the missing/duplicate number'
- 'first missing positive'
Visual clues in the prompt
- “'numbers 1 to n'”
- “'find all disappeared numbers'”
- “'find the duplicate'”
Template
1i = 02while i < n:3 home = nums[i] - 14 if nums[i] != nums[home]:5 nums[i], nums[home] = nums[home], nums[i]6 else:7 i += 1
Common variations
- Missing number
- All disappeared numbers
- Find duplicate
- First missing positive
Bit Manipulation
Treat integers as bit arrays — XOR to cancel, masks to test/set, bitmasks as sets.
When to identify it
- 'appears twice except one'
- 'without extra space'
- Subsets of ≤ 20 items
Visual clues in the prompt
- “'single number'”
- “'count bits'”
- “'power of two'”
Template
1result = 02for x in nums:3 result ^= x 4return result
Common variations
- XOR (single/missing)
- n & (n-1) tricks
- Bitmask sets
- Bitmask DP