Lesson 06new · v2 format
How to Read a Problem: Constraints, Clues & Complexity Budgets
Before you write a line of code, the problem statement has already told you which algorithm to use.
01Why it matters & the intuition
Most people who 'can't do LeetCode' can follow any solution once they see it. What they are missing is the step before the solution: reading the problem and narrowing thousands of possible approaches down to one or two. That step is a skill with rules, and this lesson teaches the rules.
You don't need to know the algorithms yet. By the end of this page you will be able to look at a problem and say how fast the solution must be and which family of techniques to try — the rest of the course fills in each family.
Think of it like…
A doctor doesn't try every medicine. They read the symptoms — fever, rash, where it hurts — and each symptom rules whole diseases in or out. The constraints are the patient's vital signs: they tell you how much time you're allowed. The clue words ("sorted", "contiguous", "all combinations", "shortest") are the symptoms: each one points at a family of treatments.
02See it move
Pick a constraint the way it appears in a problem, or drag the slider. Watch which complexity classes survive — the teal row is the slowest solution you're allowed to write.
| Class | Operations | Time at 10⁸/s | Verdict |
|---|---|---|---|
| O(n!)try every ordering | ∞ | heat death of the universe | too slow |
| O(2ⁿ)try every subset | ∞ | heat death of the universe | too slow |
| O(n³)triple loop, interval DP | 1.0×10^15 | 116 days | too slow |
| O(n²)every pair, 2-D DP | 1.0×10^10 | 100.0 s | too slow |
| O(n log n)sort, heap, divide & conquer | 1.7×10^6 | 17 ms | your budget |
| O(n)one pass, hash map, window | 1.0×10^5 | 1 ms | fits |
| O(log n)binary search | 17 | < 1 ms | fits |
03Key ideas
Step 1 — Restate it in one line
Write input → output in your own words: "array of prices → max profit from one buy and one later sell". If you can't restate it, you'll solve the wrong problem. Note the output type: a number, a boolean, one item, or all items (a strong hint on its own).
Step 2 — Read the constraints first
Judges allow roughly 10⁸ simple operations per second. So n ≤ 10⁵ means O(n²) = 10¹⁰ is too slow, but O(n log n) ≈ 1.7 × 10⁶ is easy. The constraint is the problem setter telling you the target complexity.
Step 3 — Circle the clue words
"sorted" → binary search or two pointers. "contiguous subarray / substring" → sliding window or prefix sums. "all combinations / every arrangement" → backtracking. "shortest number of steps" → BFS. "number of ways / minimum cost" → dynamic programming. "k-th / top k" → heap or quickselect.
Step 4 — Say the brute force out loud
Always name the simplest correct approach and its cost first. It gives you a fallback, and comparing its cost to the budget tells you exactly how much faster you need to be.
Step 5 — Find the bottleneck
Ask: what does the brute force repeat? Rescanning for a partner → remember what you've seen (hash map). Re-summing overlapping ranges → reuse the previous window. Re-solving the same sub-question → cache it (DP). The structure you pick is whatever removes the repetition.
Edge cases come from constraints too
0 ≤ n means empty input is legal. Negative values break "sliding window on sums". Values up to 10⁹ mean sums can exceed 32-bit ints in other languages. Duplicates allowed? Read it twice.
04Build it from scratch
A clean reference implementation. Read it line by line — then close it and write your own in the lab below.
// The 5-step read, written as a checklist you can keep next to your editor.
interface ProblemRead {
restated: string; // "array of prices -> max profit from one buy then one later sell"
n: number; // largest input size from the constraints
budget: string; // fastest-growing complexity that still fits ~1e8 operations
clues: string[]; // words that point at a technique family
bruteForce: string; // simplest correct idea + its cost
bottleneck: string; // what the brute force repeats
}
// Step 2 made mechanical: the biggest complexity class that fits the budget.
const OPS_PER_SECOND = 1e8;
const CLASSES: [label: string, cost: (n: number) => number][] = [
["O(n!)", (n) => { let f = 1; for (let i = 2; i <= n; i++) f *= i; return f; }],
["O(2^n)", (n) => 2 ** n],
["O(n^3)", (n) => n ** 3],
["O(n^2)", (n) => n ** 2],
["O(n log n)", (n) => n * Math.log2(Math.max(n, 2))],
["O(n)", (n) => n],
];
function complexityBudget(n: number): string {
for (const [label, cost] of CLASSES) {
if (cost(n) <= OPS_PER_SECOND) return label; // slowest class that still fits
}
return "O(log n)";
}
complexityBudget(12); // "O(2^n)" — 12! = 479M is too slow, 2^12 = 4096 is fine
complexityBudget(1e5); // "O(n log n)"
complexityBudget(1e12); // "O(log n)" — only binary search / math survives05Complexity
| Constraint says | Budget — aim for | |
|---|---|---|
| n ≤ 10–11 | O(n!) — try every ordering | — |
| n ≤ 20–25 | O(2ⁿ) — try every subset | — |
| n ≤ 300–500 | O(n³) — triple loop / interval DP | — |
| n ≤ 5,000–10⁴ | O(n²) — every pair / 2-D DP | — |
| n ≤ 10⁵–10⁶ | O(n log n) or O(n) — sort, heap, hash, window | — |
| n ≤ 10⁸ | O(n) with a tiny constant | — |
| n up to 10⁹ – 10¹⁸ | O(log n) or O(1) — binary search on the answer, math | — |
06Recognise it in a problem
These phrases in a problem statement should make you reach for a specific tool before you write any code.
| If the problem says… | …reach for |
|---|---|
| "sorted" array or "find position" | Binary search, or two pointers from both ends |
| "contiguous", "subarray", "substring", "window" | Sliding window or prefix sums |
| "pair / two numbers that add to", "seen before", "duplicate" | Hash map or set |
| "all", "every combination / permutation / subset", n ≤ 20 | Backtracking — exponential is expected |
| "shortest path / fewest steps", grid or network, no weights | BFS |
| "prerequisites", "order tasks", "depends on" | Topological sort on a directed graph |
| "number of ways", "minimum / maximum cost", choices at each step | Dynamic programming |
| "k-th largest", "top k", "closest k" | Heap (priority queue) or quickselect |
| "next greater / smaller element", "days until warmer" | Monotonic stack |
| "merge intervals", "meeting rooms", overlapping ranges | Sort by start or end, then one scan |
07Decode drills
You won’t solve these here. Read each problem the way an experienced engineer would: circle the clues in your head, pick the technique family and the complexity you must hit. Then check the clues you missed.
Matching transactions
You are given a list of transaction amounts and a target value. Return true if any two different transactions add up exactly to the target.
Constraints: 2 ≤ n ≤ 10⁵ · −10⁹ ≤ amount ≤ 10⁹
08Check your understanding
09Code lab
Write Python(or switch to JavaScript) and run it against real test cases. Python runs inside your browser — nothing is uploaded — and a C++ reference solution is under “Solution”.
Compute the complexity budget
Write budget(n) that returns the most expensive complexity class that still fits — i.e. the first of "O(n!)", "O(2^n)", "O(n^3)", "O(n^2)", "O(n log n)", "O(n)" whose cost for this n is at most 10⁸ operations — or "O(log n)" if none fit. Use n * Math.log2(n) for n log n.