🎉 All 30 days are live — the full DSA-30 course, from Big-O to System Design. See the roadmap →
Cheat Sheet

Cheat Sheet

The one-page reference. Skim it the morning of an interview to reload the numbers and the templates into working memory. For the “which technique?” decision guide, see the Pattern Map.

The complexity ladder

For most interview inputs (n up to ~10⁵–10⁶), here’s what each complexity buys you:

ComplexityNameFeels likeOK up to (~1s)
O(1)constantinstantany n
O(log n)logarithmicbinary searcheffectively unlimited
O(n)linearone pass~10⁸
O(n log n)linearithmicsorting~10⁶–10⁷
O(n²)quadraticnested loops~10⁴
O(2ⁿ)exponentialall subsets~20–25
O(n!)factorialall permutations~10–12

Read the constraint backward into a target Big-O. n ≤ 20 → an exponential bitmask/backtracking solution is fine. n ≤ 10⁵ → you need O(n log n) or better (sorting or hashing). n ≤ 10⁹ → you can’t even read all the input; it’s O(log n) (binary search) or math. The constraint is a hint about the intended approach.

Data-structure operations

StructureAccessSearchInsertDeleteNote
ArrayO(1)O(n)O(n)O(n)contiguous, cache-friendly
Hash map / setO(1)*O(1)*O(1)**amortized; the universal speedup
Balanced BST / TreeMapO(log n)O(log n)O(log n)O(log n)keeps keys sorted
Heap (binary)O(1) peekO(n)O(log n)O(log n) poptop-k, priority
Stack / QueueO(1)O(1)LIFO / FIFO
TrieO(L)O(L)O(L)L = key length; prefix queries
Union-FindO(α(n))O(α(n))near-constant connectivity
Segment tree / BITO(log n)O(log n)O(log n)range query on mutable data

Algorithm complexities

AlgorithmTimeSpaceChapter
Binary searchO(log n)O(1)Day 13
Merge / Quick / Heap sortO(n log n)O(n) / O(log n) / O(1)Day 11–12
BFS / DFSO(V + E)O(V)Day 10
Dijkstra (binary heap)O((V + E) log V)O(V)Day 21
Topological sortO(V + E)O(V)Day 23
1-D / 2-D DPO(n) / O(n·m)same or reducedDay 14
Sliding windowO(n)O(k)Day 24
KMP / Z-algorithmO(n + m)O(m)Day 27

Templates worth memorizing

# Binary search (lower bound) — Day 13
lo, hi = 0, len(a)
while lo < hi:
    mid = (lo + hi) // 2
    if a[mid] < target: lo = mid + 1
    else: hi = mid
# lo is the first index >= target
 
# Sliding window (variable) — Day 24
left = 0
for right in range(len(a)):
    add(a[right])
    while window_invalid():
        remove(a[left]); left += 1
    best = max(best, right - left + 1)
 
# BFS — Day 10
from collections import deque
q = deque([start]); seen = {start}
while q:
    node = q.popleft()
    for nxt in graph[node]:
        if nxt not in seen:
            seen.add(nxt); q.append(nxt)

The universal solve loop

When you’re stuck, run this out loud, every time:

  1. Restate the problem; clarify constraints (n? edges? empty input? what to return when there’s no answer?).
  2. Read the constraints into a target Big-O.
  3. Brute force first — get something correct, state its complexity.
  4. Find the repeated work — that’s where the optimization lives.
  5. Match it to a pattern (Pattern Map).
  6. Code, test (incl. edges), state final complexity.
⚠️

Treat the pattern map as strong priors, not a lookup table. Some problems are novel, and some combine two patterns (e.g. binary search on the answer with a greedy feasibility check). If the clue points one way but the details don’t fit — trust the details.

Finished this page?