Interview Cheat Sheet

Complete Reference | Pattern Selector | Complexity Tables | C++ STL | Top 50 Problems

📚 12 Chapters Covered 🏆 50+ Top Problems 📊 All Complexity Tables FAANG Target Level

🗺 Section 1 — Pattern Selector: Which Algorithm to Use?

Read the problem, identify the signals, select the pattern. This table covers the decision process for ~90% of LeetCode-style problems.

If the problem involves… Primary Pattern Secondary / Fallback
Sorted array + find/count targetBinary SearchTwo Pointers
Optimal contiguous subarray/substringSliding WindowTwo Pointers
Pairs/triplets summing to targetTwo Pointers (sorted)Hash Map (unsorted)
Next greater/smaller in arrayMonotonic Stack
Histogram / rectangle areaMonotonic StackDivide & Conquer
Prefix queries / autocompleteTrieHash Set
Dynamic connectivity / cycle detectionUnion-FindBFS/DFS
Shortest path (unweighted)BFS
Shortest path (weighted, non-neg)Dijkstra (BFS + Min-Heap)
Shortest path (negative edges)Bellman-Ford
Minimum Spanning TreeKruskal (Union-Find) or Prim
Topological order / dependencyKahn's BFS or DFS post-order
All subsets / combinations / pathsBacktracking
Minimum / maximum over sequenceDynamic ProgrammingGreedy (if exchange arg holds)
Count ways / number of pathsDP (counting)
String alignment / edit operations2D DP (LCS / Edit Distance)
Pack items into capacity0/1 or Unbounded Knapsack DP
Interval scheduling (max non-overlap)Greedy (earliest finish)
Merge / insert intervalsSort + linear scan
Kth largest / smallest elementMin-Heap of size kQuickSelect O(n) avg
Running medianTwo Heaps (max-heap + min-heap)
Merge k sorted lists/arraysMin-Heap of k heads
Level-order tree traversalBFS
In/pre/post-order traversalDFS (recursive or iterative)
LCA in binary treeDFS post-orderBinary lifting for repeated queries
Detect cycle in graphUnion-Find or DFS with colour
Anagram / frequency matchingSliding Window + freq arrayHash Map
Palindrome check / constructionTwo Pointers or DP
Calculator / expression parsingStackRecursive descent

📊 Section 2 — Master Complexity Reference

2.1 — Data Structures

StructureAccessSearchInsertDeleteSpace
ArrayO(1)O(n)O(n)O(n)O(n)
Linked ListO(n)O(n)O(1) headO(1) given ptrO(n)
Stack / QueueO(n)O(n)O(1)O(1)O(n)
Hash Map / SetO(1) avgO(1) avgO(1) avgO(1) avgO(n)
Binary Search TreeO(log n) avgO(log n) avgO(log n) avgO(log n) avgO(n)
AVL / Red-Black TreeO(log n)O(log n)O(log n)O(log n)O(n)
Min/Max HeapO(1) peekO(n)O(log n)O(log n)O(n)
TrieO(L)O(L)O(L)O(L)O(n*L*26)
Union-Find (DSU)O(alpha(n))O(alpha(n))O(n)

2.2 — Sorting Algorithms

AlgorithmBestAverageWorstSpaceStable?
Bubble SortO(n)O(n²)O(n²)O(1)✅ Yes
Insertion SortO(n)O(n²)O(n²)O(1)✅ Yes
Selection SortO(n²)O(n²)O(n²)O(1)❌ No
Merge SortO(n log n)O(n log n)O(n log n)O(n)✅ Yes
Quick SortO(n log n)O(n log n)O(n²)O(log n)❌ No
Heap SortO(n log n)O(n log n)O(n log n)O(1)❌ No
Counting SortO(n+k)O(n+k)O(n+k)O(k)✅ Yes
Radix SortO(d*(n+k))O(d*(n+k))O(d*(n+k))O(n+k)✅ Yes
Tim Sort (std::sort)O(n)O(n log n)O(n log n)O(n)✅ Yes

2.3 — Graph Algorithms

AlgorithmTimeSpaceUse Case
BFSO(V+E)O(V)Shortest path (unweighted), level order
DFSO(V+E)O(V)Cycle detection, topological sort, connected components
DijkstraO((V+E) log V)O(V)Shortest path, non-negative weights
Bellman-FordO(V*E)O(V)Shortest path, negative weights, detect neg cycles
Floyd-WarshallO(V³)O(V²)All-pairs shortest path, dense graph
Kruskal MSTO(E log E)O(V)Minimum spanning tree (sparse graph)
Prim MSTO((V+E) log V)O(V)Minimum spanning tree (dense graph)
Kahn's (Topo Sort)O(V+E)O(V)Topological order, detect cycle in DAG
Tarjan SCCO(V+E)O(V)Strongly connected components

2.4 — Key DSA Algorithms

AlgorithmTimeSpaceNotes
Binary SearchO(log n)O(1)Requires sorted / monotone input
Two PointersO(n)O(1)Requires sorted or monotone property
Sliding WindowO(n)O(1) or O(k)Optimal contiguous window
Monotonic StackO(n)O(n)Each element pushed/popped at most once
Backtracking (subsets)O(2ⁿ * n)O(n)Exponential, pruning helps constant
Backtracking (permutations)O(n! * n)O(n)
Dynamic Programming 1DO(n)–O(n²)O(n)Depends on recurrence
Dynamic Programming 2DO(m*n)O(n) optLCS, Edit Distance, Grid paths
0/1 KnapsackO(n*W)O(W)Reverse capacity iteration
LIS O(n log n)O(n log n)O(n)Patience sort with binary search
Heap: BuildO(n)O(1) in-placeFloyd's build-heap
Heap: Extract/InsertO(log n)O(1)Sift-down / sift-up
Union-FindO(alpha(n))O(n)Path compression + union by rank
Trie: Insert/SearchO(L)O(L)L = length of string

⚙️ Section 3 — C++ STL Quick Reference

3.1 — Containers

// ── vector ──────────────────────────────────────────────────
vector<int> v;
v.push_back(x);      // O(1) amortised
v.pop_back();        // O(1)
v[i];                // O(1) random access
v.size(); v.empty(); v.back(); v.front();
sort(v.begin(), v.end());                // O(n log n)
reverse(v.begin(), v.end());             // O(n)
int idx = lower_bound(v.begin(),v.end(),x) - v.begin(); // O(log n)

// ── stack ────────────────────────────────────────────────────
stack<int> stk;
stk.push(x); stk.pop(); stk.top(); stk.empty();  // all O(1)

// ── queue ────────────────────────────────────────────────────
queue<int> q;
q.push(x); q.pop(); q.front(); q.back(); q.empty();  // all O(1)

// ── deque ────────────────────────────────────────────────────
deque<int> dq;
dq.push_back(x); dq.push_front(x);   // O(1)
dq.pop_back();   dq.pop_front();      // O(1)
dq[i];                                // O(1) random access

// ── priority_queue ──────────────────────────────────────────
priority_queue<int> maxH;              // max at top
priority_queue<int,vector<int>,greater<int>> minH;  // min at top
maxH.push(x); maxH.pop(); maxH.top(); // O(log n) except top

// ── set / multiset ────────────────────────────────────────────
set<int> s;                   // sorted, unique
s.insert(x); s.erase(x); s.count(x); s.find(x);  // O(log n)
s.lower_bound(x); s.upper_bound(x);               // O(log n)

// ── map / unordered_map ───────────────────────────────────────
unordered_map<string,int> um; // O(1) avg
map<string,int> m;            // O(log n), sorted by key
um[key] = val;  um.count(key);  um.find(key);
for (auto& [k,v] : um) { }  // structured binding C++17

3.2 — Useful Algorithms & Functions

// ── Numeric utilities ────────────────────────────────────────
#include <numeric>
int sum = accumulate(v.begin(), v.end(), 0);
iota(v.begin(), v.end(), 0);          // fill 0,1,2,...,n-1

// ── Min/Max ──────────────────────────────────────────────────
int mx = *max_element(v.begin(), v.end());
int mn = *min_element(v.begin(), v.end());
int res = __gcd(a, b);                // GCD, O(log min(a,b))
int res = __builtin_popcount(x);      // count set bits

// ── String ───────────────────────────────────────────────────
string s = to_string(42);
int n = stoi("42");
s.substr(start, len);                 // O(len)
s.find(sub);                          // O(n*m) naive

// ── Functional / lambda ──────────────────────────────────────
sort(v.begin(), v.end(), [](int a, int b){ return a > b; }); // descending
function<int(int)> dfs = [&](int node) -> int { return 0; }; // recursive lambda

// ── Bit operations ───────────────────────────────────────────
// x & (x-1)       → clear lowest set bit (power of 2: x&(x-1)==0)
// x | (1 << k)    → set bit k
// x & ~(1 << k)   → clear bit k
// (x >> k) & 1    → check bit k
// x ^ x = 0       → XOR self = 0 (find single number)

3.3 — Graph BFS/DFS Templates

// ── BFS from source ──────────────────────────────────────────
vector<int> dist(n, INT_MAX);
queue<int> q;
dist[src] = 0; q.push(src);
while (!q.empty()) {
    int u = q.front(); q.pop();
    for (int v : adj[u]) {
        if (dist[v] == INT_MAX) {
            dist[v] = dist[u] + 1;
            q.push(v);
        }
    }
}

// ── DFS iterative ────────────────────────────────────────────
vector<bool> visited(n, false);
stack<int> stk; stk.push(src);
while (!stk.empty()) {
    int u = stk.top(); stk.pop();
    if (visited[u]) continue;
    visited[u] = true;
    for (int v : adj[u]) if (!visited[v]) stk.push(v);
}

// ── Dijkstra ─────────────────────────────────────────────────
vector<long long> dist(n, LLONG_MAX);
priority_queue<pair<long long,int>,
               vector<pair<long long,int>>,
               greater<>> pq;
dist[src] = 0; pq.push({0, src});
while (!pq.empty()) {
    auto [d, u] = pq.top(); pq.pop();
    if (d > dist[u]) continue;  // skip stale entry
    for (auto [v, w] : adj[u]) {
        if (dist[u] + w < dist[v]) {
            dist[v] = dist[u] + w;
            pq.push({dist[v], v});
        }
    }
}

🎯 Section 4 — Interview Problem-Solving Framework

Step 1 — UNDERSTAND (2–3 min)

  • Restate the problem in your own words. Confirm your understanding with the interviewer.
  • Ask about constraints: array size n, value range, negative numbers, duplicates, sorted?
  • Ask about edge cases: empty input, single element, all equal, n=1.
  • Clarify output format: return value, modify in-place, 1-indexed or 0-indexed?
  • Write 1–2 concrete examples including an edge case.

Step 2 — PLAN (3–5 min)

  • State the brute force first. Say: 'The naive solution is O(n²) by…'
  • Identify the bottleneck: inner loop, repeated work, wrong data structure.
  • Map to a known pattern using the pattern selector (Section 1).
  • State your approach clearly and the expected complexity before writing code.

Step 3 — CODE (10–15 min)

  • Write clean, readable code. Use meaningful variable names (lo/hi over i/j for pointers).
  • Code the happy path first. Add edge case handling at the start.
  • Think out loud as you code: 'Here I'm updating the window by removing the leftmost element…'
  • Avoid premature optimisation. Get a working solution, then optimise.

Step 4 — TEST (3–5 min)

  • Trace through your example from Step 1 line by line.
  • Test with edge cases: empty array, single element, all same, maximum n.
  • For graph problems: test disconnected graph, single node, cycle.
  • Announce bugs before fixing: 'I see that my loop should be <= not <, let me fix that.'

Step 5 — OPTIMISE & DISCUSS (2–3 min)

  • State final time and space complexity, explain why.
  • Discuss trade-offs: 'We could reduce space from O(n) to O(1) by using rolling variables.'
  • Mention alternative approaches and proactively discuss follow-up variations.

⚡ Section 5 — Complexity Signals from Constraints

FAANG interviewers set constraints that hint at the expected time complexity. Use these to validate your approach before coding.

Constraint (n)Target ComplexityAlgorithms That Fit
n ≤ 10O(n!) or O(2ⁿ · n)Backtracking (all permutations/subsets), brute force
n ≤ 20O(2ⁿ)Bitmask DP, backtracking with heavy pruning
n ≤ 100O(n³)Floyd-Warshall, interval DP, 3D DP
n ≤ 1,000O(n²)2D DP (LCS, Edit Distance), O(n²) DP, naive graph
n ≤ 10,000O(n² tight) or O(n·√n)Acceptable O(n²), Sqrt decomposition
n ≤ 100,000O(n log n)Sorting, binary search, segment tree, heap, Dijkstra
n ≤ 1,000,000O(n)Two pointers, sliding window, monotonic stack, hash map
n ≤ 10⁹O(log n)Binary search on answer, math formula
n ≤ 10¹⁸O(log n) or O(√n)Binary search, fast exponentiation, prime factorisation

Quick Sanity Check: Will My Solution TLE?

  • Modern CPUs execute ~10⁸ simple operations per second.
  • O(n²) with n=10⁵: 10¹⁰ ops → TLE. Need O(n log n) or better.
  • O(n log n) with n=10⁶: ~2·10⁷ ops → Fast ✓
  • O(2ⁿ) with n=30: 10⁹ ops → borderline TLE. With n=20: 10⁶ ops → OK.
  • O(n!) with n=12: 4.8·10⁸ ops → borderline. With n=10: 3.6·10⁶ ops → OK.
  • When unsure: calculate n² or n·log(n) mentally and check against 10⁸.

🏆 Section 6 — Top 50 Must-Know LeetCode Problems

Arrays & Hashing

#ProblemPatternDifficulty
1Two SumHash MapEasy
2Best Time to Buy & Sell StockGreedy / Kadane variantEasy
3Contains DuplicateHash SetEasy
4Product of Array Except SelfPrefix ProductMedium
5Maximum Subarray (Kadane)Greedy / DPMedium
6Maximum Product SubarrayDP (track min & max)Medium
7Find Minimum in Rotated ArrayBinary SearchMedium
83SumSort + Two PointersMedium
9Container With Most WaterTwo PointersMedium
10Trapping Rain WaterMonotonic Stack / Two PtrHard

Strings

#ProblemPatternDifficulty
11Longest Substring Without RepeatingSliding WindowMedium
12Minimum Window SubstringSliding WindowHard
13Valid AnagramFrequency CountEasy
14Group AnagramsSort as Key + Hash MapMedium
15Longest Palindromic SubstringExpand Around Centre / DPMedium
16Encode and Decode StringsPrefix Length EncodingMedium
17Valid ParenthesesStackEasy

Trees & Graphs

#ProblemPatternDifficulty
18Invert Binary TreeDFS/BFSEasy
19Maximum Depth of Binary TreeDFSEasy
20Same TreeDFSEasy
21Binary Tree Level Order TraversalBFSMedium
22Validate Binary Search TreeDFS + boundsMedium
23Lowest Common AncestorDFS post-orderMedium
24Binary Tree Right Side ViewBFS (last per level)Medium
25Clone GraphDFS + Hash MapMedium
26Course Schedule (Topo Sort)Kahn's BFSMedium
27Number of IslandsBFS/DFS or Union-FindMedium
28Word LadderBFS + LevelHard
29Word Search IITrie + DFS BacktrackHard

Binary Search & Heaps

#ProblemPatternDifficulty
30Binary SearchClassic Template 1Easy
31Search in Rotated Sorted ArrayRotated Binary SearchMedium
32Find Minimum in Rotated ArrayCompare mid to hiMedium
33Koko Eating BananasAnswer Space BSMedium
34Kth Largest Element in ArrayMin-Heap of size kMedium
35Merge K Sorted ListsMin-Heap of k headsHard
36Top K Frequent ElementsMin-Heap or Bucket SortMedium
37Find Median from Data StreamTwo HeapsHard

Dynamic Programming

#ProblemPatternDifficulty
38Climbing StairsFibonacci 1D DPEasy
39House Robber1D DP rollingMedium
40Coin ChangeUnbounded KnapsackMedium
41Longest Increasing Subsequence1D DP or O(n log n)Medium
42Longest Common Subsequence2D DPMedium
43Edit Distance2D DP 3-way recurrenceHard
44Partition Equal Subset Sum0/1 KnapsackMedium
45Unique PathsGrid path counting DPMedium
46Word Break1D DP + setMedium
47Best Time to Buy Stock w/ CooldownState Machine DPMedium
48Burst BalloonsInterval DPHard

Backtracking & Stack

#ProblemPatternDifficulty
49Combination SumBacktracking + pruningMedium
50N-QueensBacktracking + O(1) checkHard

⚠️ Section 7 — Universal Mistakes & Red Flags

7.1 — Integer Overflow

// MISTAKE: int overflow in sum/product
int sum = 0;
for (int x : nums) sum += x; // overflows if nums has large values

// FIX: use long long
long long sum = 0;
for (int x : nums) sum += x;

// MISTAKE: mid calculation overflow
int mid = (lo + hi) / 2;   // lo+hi can overflow if both ~2^30

// FIX:
int mid = lo + (hi - lo) / 2;

// MISTAKE: multiplying two ints before assigning to long long
long long area = height * width;   // height*width computed as int first!

// FIX:
long long area = (long long)height * width;

7.2 — Off-By-One

// Binary Search variants:
while (lo <= hi)  { hi = mid - 1; lo = mid + 1; }  // exact search
while (lo < hi)   { hi = mid;     lo = mid + 1; }  // lower bound

// Array bounds: always check before accessing
if (i >= 0 && i < n && j >= 0 && j < m) grid[i][j];

// Substring length
s.substr(start, end - start + 1); // inclusive end
s.substr(start, end - start);     // exclusive end

7.3 — Graph & Tree Pitfalls

// MISTAKE: Forgetting to check visited before pushing to BFS queue -> infinite loop
// FIX: mark visited WHEN PUSHING, not when popping
if (!visited[v]) { visited[v] = true; q.push(v); }

// Dijkstra: forgetting to skip stale heap entries
auto [d, u] = pq.top(); pq.pop();
if (d > dist[u]) continue; // CRITICAL: skip outdated entries

// Tree: confusing null check
if (!node) return 0;             // null node contributes 0 to depth
if (!node->left && !node->right) // leaf node check

7.4 — DP Pitfalls

// Missing base case: dp[0] must be set before the loop
vector<int> dp(amount+1, amount+1);
dp[0] = 0; // CRITICAL base case

// 0/1 Knapsack: iterating capacity forward (allows item reuse)
for (int cap = w[i]; cap <= W; cap++) // WRONG: unbounded knapsack
for (int cap = W; cap >= w[i]; cap--) // CORRECT: 0/1 knapsack

// 2D DP string indexing: text[i-1] not text[i] when using 1-indexed dp
if (s1[i-1] == s2[j-1]) dp[i][j] = dp[i-1][j-1] + 1;

📈 Section 8 — Big-O Growth Cheat Card

NotationNamen=10n=100n=1,000n=10⁶
O(1)Constant1111
O(log n)Logarithmic371020
O(√n)Square Root310321,000
O(n)Linear101001,0001,000,000
O(n log n)Linearithmic3366410,00020,000,000
O(n²)Quadratic10010,00010⁶10¹² (TLE)
O(n³)Cubic1,00010⁶10⁹ (TLE)
O(2ⁿ)Exponential1,02410³⁰ (TLE)
O(n!)Factorial3.6M10¹⁵⁷ (TLE)

Rules for Simplifying Big-O

  • DROP CONSTANTS: O(3n) = O(n). O(2n² + 5n) = O(n²).
  • DROP LOWER TERMS: O(n² + n) = O(n²). O(n log n + n) = O(n log n).
  • DIFFERENT INPUTS use different variables: O(a + b) is NOT O(n). Keep separate.
  • NESTED LOOPS multiply: outer O(n) × inner O(n) = O(n²). Unless inner shrinks per outer.
  • RECURSION: T(n) = 2T(n/2) + O(n) ⇒ O(n log n) by Master Theorem (Merge Sort).
  • AMORTISED: dynamic array doubling is O(1) amortised per push_back despite occasional O(n) resize.

🔥 Section 9 — Last-Minute Interview Reminders

Before You Code

  • Always ask: what are the constraints? (n, value range, sorted?)
  • Always ask: can there be duplicates? negative numbers? empty input?
  • State brute force first, then optimise. Never jump straight to the optimal.
  • Announce your approach and complexity BEFORE writing code.

While Coding

  • Use long long for sums/products that might exceed 2×10⁹.
  • Use lo + (hi - lo) / 2, never (lo + hi) / 2.
  • Check array bounds before every access: if (i >= 0 && i < n).
  • In BFS: mark visited when PUSHING, not when POPPING.
  • In Dijkstra: skip stale heap entries with if (d > dist[u]) continue.
  • In 0/1 Knapsack 1D: iterate capacity in REVERSE.
  • In Backtracking: always undo (pop_back / used[i]=false) after recursion.

Common Gotchas by Topic

  • BINARY SEARCH: lo <= hi for exact, lo < hi for bound. hi = n (not n-1) for bound.
  • TWO POINTERS: only works on sorted arrays or when property is monotone.
  • SLIDING WINDOW: shrink left WHILE constraint violated (while, not if).
  • HEAP: C++ priority_queue is max-heap by default. For min-heap: greater<int>.
  • GRAPH BFS: use queue, not stack. Visited set prevents revisiting.
  • TREE DFS: handle null node at start: if (!node) return base_val.
  • BACKTRACKING: collect at every node for subsets; only at leaves for permutations.
  • DP: define state precisely BEFORE writing recurrence. Base cases BEFORE loop.
  • TRIE: search() returns false if isEnd=false even if path exists.
  • UNION-FIND: compare find(a)==find(b), NOT a==b.

Complexity Red Flags

  • O(n²) with n > 10⁴: you probably need sliding window, binary search, or a hash map.
  • O(2ⁿ) with n > 25: need DP or bitmask DP instead of backtracking.
  • O(n!) with n > 12: almost certainly needs pruning or a completely different approach.
  • Calling sort() inside a loop: O(n² log n) — sort once outside.
  • Using substr() inside a loop without memoisation: O(n² · L) — cache or use indices.

🎓 End of DSA Course — Chapters 0–12 Complete!

Arrays | Linked Lists | Stacks & Queues | Hashing | Trees | Graphs | Heaps | Greedy | Binary Search | Backtracking | Dynamic Programming | Bonus Topics