revise · the night before
The last-night sheet
Read this once, slowly. Then close the laptop and sleep. Sleep does more for tomorrow than one more problem.
If you see this → think that
One trigger per pattern chapter. Read the left side, say the right side before you look.
- "Find two/k items that add up to / match something"
- HashMap of what you've seen (or sort + two pointers) Mindset
- A loop variable that halves or doubles (
i /= 2,i *= 2,lo..hishrinking by half) - O(log n) Big-O
- The answer for n is defined using the answer for n − 1, n / 2, or a sub-part
- Write the recurrence first, then the base case Recursion
- "The answer may be large, return it modulo 10⁹+7"
- Reduce after every + and ×, use
longfor products, divide with Fermat's inverse Math & Numbers - "Contiguous subarray" with the max/min sum
- Kadane: extend or restart at each index Arrays & Strings
- "Spiral order", "layer by layer", "ring"
- Four shrinking walls, with guards for a single leftover row or column Matrices
- The array is sorted and you need a pair / triplet with some sum
- Opposite-ends pointers Two Pointers
- "Contiguous subarray" or "substring" + longest / shortest / maximum / minimum
- Variable sliding window Sliding Window
- "Find a pair / complement" in an unsorted array, return indices
- HashMap value → index, look up
target − xbefore storing x Hashing - "Middle of the list", "split in half", "palindrome list"
- slow / fast pointers (fast moves 2) Linked Lists
- Brackets, tags or anything that opens and closes and can nest
- Push openers; a closer must match the top Stacks
- "Process in the order they arrive", "first come first served", task scheduling
- Plain FIFO queue (ArrayDeque) Queues
- Input is sorted (or each row of a matrix is) and you need O(log n)
- Classic binary search or lower/upper bound Binary Search
- Intervals, meetings, schedules — anything with start/end
- Sort by start (or end), then sweep once Sorting
- "Implement atoi", "parse this number", "is this a valid number"
- A small state machine: spaces → sign → digits (→ '.' → exponent), with an overflow guard Parsing
- "Level", "row", "zigzag", "right side view", "average of each level"
- BFS with
size = queue.size()per round Traversals - "Maximum/minimum depth", "height", "is balanced"
- Postorder: return the height up; use −1 or a record for "invalid" Tree Recursion
- The input is a BST and you need sorted order
- Inorder traversal (iterative with a stack if you need to stop early) BST
- "k largest", "k smallest", "k closest", "top k frequent"
- Size-k heap in the opposite direction (or quickselect / buckets) Heaps
- "prefix", "starts with", "autocomplete", "suggestions", "typeahead"
- Trie — walk to the prefix node Tries
- "Minimum number of steps / moves / transformations" with all moves costing the same
- BFS from the start; level = answer Graphs
- "Minimum cost / time / distance" with weighted edges
- Dijkstra (if no negative weights) Shortest Paths
- "Groups", "connected", "same component", "friends of friends", "merge accounts"
- Union-Find (or DFS) over the connection relation Union-Find & MST
- "prerequisites", "depends on", "must happen before", "build order"
- Directed graph + topological sort Topo Sort
- "Use every ticket / edge / domino exactly once"
- Euler path: degree check + Hierholzer (add when stuck, reverse) Advanced Graphs
- "Return all …" (subsets, permutations, combinations, partitions, valid strings)
- Backtracking — the output itself is exponential, so nothing faster exists Backtracking
- "Can you reach the end?" / "fewest jumps"
- Furthest reach; BFS levels without a queue Greedy
- "Merge", "insert", "union of ranges"
- Sort by start, extend the last group Intervals
- "Every element appears twice except one"
- XOR everything: pairs cancel Bits
- "Count the number of ways…"
- Counting DP: dp[state] = sum of ways of the smaller states it comes from Dynamic Programming
- Buy and sell with a cooldown, a fee, or at most k trades
- State-machine DP: one variable per mode, one max() per arrow DP Patterns
- "insert, delete and getRandom, all in O(1)"
- HashMap value → index + ArrayList; delete by swapping with the last element Design DS
- Many range-sum queries, no updates
- Prefix sums (Hashing & Prefix Sums chapter) — don't overbuild Range Queries & Strings
Complexity budget
Find the biggest n in the constraints. Its row tells you how fast your idea must be (about 10⁸ simple steps a second).
| max n | allowed | typical idea |
|---|---|---|
| ≤ 10 | O(n!) | try every permutation |
| ≤ 20 | O(2ⁿ) | subsets, bitmask DP |
| ≤ 500 | O(n³) | triple loops, Floyd–Warshall, interval DP |
| ≤ ~5,000 (10⁴ borderline) | O(n²) | all pairs, 2D DP |
| ≤ 10⁶ | O(n log n) | sorting, heaps, binary search per element |
| ≤ 10⁸ | O(n) | single pass, math |
| > 10⁸ | O(log n) or O(1) | binary search on the answer, formulas |
The 45-minute plan, in brief
You never have to wonder what comes next. The full version, with what to say: the 45-minute plan.
- 3 minClarifyMake sure you are solving the right problem.
- 2 minExamplesTurn the words into one small, concrete case.
- 3 minBrute forcePut a correct answer on the table, even a slow one.
- 4 minOptimiseFind the slow part and fix it with the right data structure.
- 18 minCodeTranslate the agreed plan into clean Java, talking as you go.
- 8 minTestFind your own bugs before the interviewer does.
- 7 minComplexity & follow-upsShow you know what your solution costs and how it would change.
Java traps that fail hidden tests
Each one passes the small examples and fails the big hidden ones. The fix is the habit to keep.
- == on Integer Compare wrappers with
.equals(), or unbox tointfirst. Never==onInteger. - Comparing HashMap counts
count.get(a).equals(count.get(b)), orObjects.equals(x, y)if a value can be null. - int overflow Use
longwhen a sum can pass about 2 × 10⁹, orMath.addExactto fail loudly. - Binary search mid Write
int mid = lo + (hi - lo) / 2;in every binary search. Bas itna yaad rakho. - char + 1 When you want a letter, cast:
(char) (c + 1). - Digit char to int
c - '0'for a digit,c - 'a'for a letter's index. - Arrays.asList then add
new ArrayList<>(Arrays.asList(1, 2, 3))when the list must grow. - Arrays.asList(int[]) Box it:
Arrays.stream(nums).boxed().collect(Collectors.toList()), or start from anInteger[]. - Reassign vs mutate To give back a new array,
returnit. To change the caller's data, change the object, not the variable. - result.add(path) Add a copy:
result.add(new ArrayList<>(path));
One trap per chapter
The mistake each chapter warns about most. If one feels new, that's your five minutes tomorrow morning.
- 01 · Java Memory
==on objects compares references. UseequalsforString/IntegerandArrays.equalsfor arrays. Literals only look safe because they are pooled. - 02 · Java Arrays & Strings
arr.length·s.length()·list.size(). And==on arrays or strings compares references — useArrays.equals/equals. - 03 · Java OOP Override
equalswithouthashCodeand HashSet/HashMap stop finding equal keys. Override both, from the same fields. - 04 · I/O & Debugging PrintWriter without
flush()prints nothing → WA.nextInt()thennextLine()returns "". Debug prints on stdout → WA. - 05 · Java Toolkit
Integer==compares references: true for −128..127 (the cache), false for 128 on a default JVM. Useequals, or unbox toint. - 06 · Mindset Coding before understanding. Most wrong answers solve a slightly different problem. Restate it and run one example by hand first.
- 07 · Big-O Hidden loops:
list.contains,list.remove(0),substring,s += xare O(n). Inside a loop they quietly make O(n²). - 08 · Recursion No reachable base case → frames pile up →
StackOverflowError. Java has no tail-call optimization, so depth 10⁴–10⁵ is risky. - 09 · Math & Numbers
(a * b) % Mwith ints overflows before the%. Write(long) a * b % M. - 10 · Arrays & Strings
s += cin a loop is O(n²): every += copies the whole string. Build withStringBuilder, calltoString()once. - 11 · Matrices Writing cells while you still read their old values breaks Game of Life and Set Zeroes. Freeze a copy, or keep old + new in one cell.
- 12 · Two Pointers
l <= rpairs an element with itself. Pair problems usel < r. - 13 · Sliding Window Negative numbers break sum windows: removing one can raise the sum. Use prefix sums + a
HashMapinstead. - 14 · Hashing Override
equalswithouthashCode(or change a key afterput) and the entry is lost: lookups go to the wrong bucket. - 15 · Linked Lists Overwriting
curr.nextbefore saving it loses the rest of the list. Forgettingtail.next = nullafter splitting creates a cycle. - 16 · Stacks
pop()on an emptyArrayDequethrows;peek()returns null. CheckisEmpty()first — and check the stack is empty at the end. - 17 · Queues
head == tailmeans both empty and full — keep asize. Stepping left?(head − 1 + k) % k, because Java's%can be negative. - 18 · Binary Search
(lo + hi) / 2overflows past 2³¹ − 1. Writelo + (hi − lo) / 2— the JDK itself carried this bug for about nine years. - 19 · Sorting
(a, b) -> a - boverflows:MIN_VALUE - 1wraps to a big positive. UseInteger.compare(a, b)orComparator.comparingInt. - 20 · Parsing Overflow: check
result > (MAX - d) / 10beforeresult * 10 + d. After the multiply it has already wrapped. - 21 · Traversals
for (int i = 0; i < queue.size(); i++)mixes levels — the queue grows inside the loop. Freezesizefirst. - 22 · Tree Recursion Returning the answer instead of what the parent needs: Diameter returns the height and records left + right — never returns the bend.
- 23 · BST Checking only
left.val < node.val < right.valmisses grandchildren. Pass (low, high) bounds down — asnull/long, neverInteger.MIN_VALUEsentinels. - 24 · Heaps Printing or iterating a
PriorityQueueis NOT sorted — only repeatedpoll()returns values in order. - 25 · Tries
searchmust checkisEndat the last node — otherwise "app" is "found" after inserting only "apple". - 26 · Graphs Mark visited when you enqueue, not when you poll — or the same vertex is queued many times.
- 27 · Shortest Paths Dijkstra + a negative edge = wrong answers. "Polled means final" only holds when no edge can shrink a path later.
- 28 · Union-Find & MST
parent[a] == parent[b]is not "same set" — comparefind(a) == find(b). And link roots:parent[find(a)] = find(b). - 29 · Topo Sort
[course, pre]means the arrow goes pre → course. Draw one edge on paper before you code. - 30 · Advanced Graphs Greedy "smallest next airport" can hit a dead end. Add an airport only when it's STUCK, then reverse — that splices the loops in.
- 31 · Backtracking
result.add(path)stores a reference that ends up empty. Alwaysresult.add(new ArrayList<>(path)). - 32 · Greedy Coins {1, 3, 4}, amount 6: biggest-first pays 4+1+1 (3 coins), but 3+3 is 2. Test 2–3 tiny inputs before trusting greedy.
- 33 · Intervals Touching rules differ: [1,4]+[4,5] merge in LC 56, but [1,2] and [2,3] live together in LC 435 and meeting rooms. One
<vs<=. - 34 · Bits
==binds tighter than&: write(x & m) != 0. And(x & m) == 1is only right for bit 0. - 35 · Dynamic Programming 0/1 knapsack in 1D: loop capacity DOWN. Going up lets an item be reused — that's unbounded knapsack.
- 36 · DP Patterns Never read a state you already changed today: save prev values first. Holding starts at −∞ (
MIN_VALUE / 2), never 0. - 37 · Design DS Swap-with-last: update the moved element's index, and remove val from the map last — or deleting the last element breaks.
- 38 · Range Queries & Strings Fenwick index 0 never moves (
0 & -0 == 0) — stay 1-based.updatesets a value: addval - nums[i], notval.
Tomorrow
Laptop charged, internet tested with a hotspot as backup, a quiet room, water, a pen and paper. The full checklist: the day before and the day of.
You don't need to know everything. You need to think out loud, start simple, and keep going. You have practised exactly that. Bas, ab so jao.