Fundamental Problems Tutorials
Coding interview problems worked end to end — the brute force, why it is not enough, the idea that fixes it, and clean Java and Python solutions with the edge cases that actually get you rejected.
- LeetCode 543 – Diameter of Binary TreeTagged Easy, and the pattern carries most of the Hard tree problems: the recursion returns one quantity to its caller while updating a different one globally. Depth goes up, diameter gets recorded. Why left + right is already in edges despite counting nodes, and why nonlocal in Python is the difference between working and silently returning zero.
- LeetCode 347 – Top K Frequent ElementsThe statement contains its own hint: better than O(n log n). That sentence exists to rule out sorting and a max-heap of everything — and the defence that there are usually few unique values is not a complexity argument. A min-heap capped at k works; bucket sort gets it to O(n), because frequencies are small bounded integers you can index by.
- LeetCode 219 – Contains Duplicate IIContains Duplicate with a distance limit, and the limit is what turns a set into a sliding window. Bound the set to k and a hit implies proximity for free. Plus why the last-seen map may overwrite: a closer occurrence dominates the older one forever.
- LeetCode 218 – The Skyline ProblemThe hardest problem on this track, and almost none of it is the algorithm. Sweep left to right and emit a point when the tallest active building changes. The difficulty is three tie-break rules and deleting from a heap — and one sign trick gives all three rules from a single sort.
- LeetCode 217 – Contains DuplicateA warm-up with one real decision in it, and the decision is about space. The hash set is the default; sorting is the O(1)-space alternative that mutates the input. Noticing a time-for-space trade in an Easy problem is most of what there is to say.
- LeetCode 215 – Kth Largest Element in an ArrayA menu problem: three standard answers with genuinely different trade-offs, and the interview is choosing among them out loud. Why a MIN-heap answers a largest question, why quickselect is O(n) on average, and why the random pivot is not optional.
- LeetCode 211 – Design Add and Search Words Data StructureImplement Trie with one wildcard added, and that wildcard is the whole problem. A trie search is a walk down one path; a dot turns it into a search over all of them, so the lookup stops being a loop and the complexity stops being linear.
- LeetCode 210 – Course Schedule IIProblem 207 asked whether an ordering exists; this wants the ordering, which Kahn's algorithm already had and threw away. The list IS the count. Plus why the DFS version comes out backwards, and the heap that gives the lexicographically smallest order.
- LeetCode 208 – Implement Trie (Prefix Tree)A build-the-structure question where the interview is really two things: why a trie beats a hash set for prefix queries, and the one boolean separating a word from a prefix. Every operation is independent of how many words are stored.
- LeetCode 207 – Course ScheduleCycle detection in a directed graph wearing a scheduling problem's clothes. Kahn's algorithm never looks for the cycle — it notices what is left over. And the DFS version needs THREE node states, because already-finished and currently-above-me are different facts.
- LeetCode 206 – Reverse Linked ListThe most-asked list question there is, and it is asked because four assignments in the wrong order lose the rest of the list. Save the successor before overwriting the link, return previous rather than current — and it is a building block for half the harder list problems.
- LeetCode 205 – Isomorphic StringsA one-map solution that is wrong and a two-map solution that is right, separated by a single word in the problem statement. The pair badc / baba passes every consistency check and is still not isomorphic, because b and d both map to b.
- LeetCode 204 – Count PrimesA problem about knowing an algorithm rather than deriving one. What is actually tested is the two optimisations that make the sieve fast — stop at sqrt(n), start the inner loop at p*p — and whether you can say why both follow from one fact.
- LeetCode 203 – Remove Linked List ElementsThe problem that proves the dummy-head rule problem 83 stated. Here the head CAN be removed, repeatedly, so the dummy stops being a preference and becomes what makes the code short. And you must return dummy.next, never head.
- LeetCode 202 – Happy NumberLinked List Cycle with the list replaced by a function. No nodes, no next pointer, and Floyd's algorithm works anyway — which is the point: cycle detection needs a successor function, not a data structure. Plus why the sequence must terminate at all.
- LeetCode 200 – Number of IslandsThe most common graph question in interviews, and it does not look like one — recognising that a grid is a graph is most of what is being tested. Count starts and erase the island so it cannot be counted twice. Why you must mark visited before recursing, the input-mutation trade to say out loud, and when the recursion depth forces BFS.
- LeetCode 199 – Binary Tree Right Side ViewThe clearest illustration that how you traverse and what you record are independent: level order with one line changed. The visible node may be a LEFT child — rightmost at its depth, not on the right spine — which is what any walk-down-the-right-side answer gets wrong.
- LeetCode 198 – House RobberThe DP that introduces a choice: Climbing Stairs counted branches and added them, this picks the better of two. Same dependencies, different combiner. And the alternating greedy everyone proposes fails on [2,1,1,2], where the best answer skips two houses in a row.
- LeetCode 189 – Rotate ArrayThe array version of Reverse Words in a String, using the identical three-reversal trick. It is also where forgetting k %= n turns a correct algorithm into an exception, and where the Python one-liner rebinds a local name so the caller sees nothing at all.
- LeetCode 173 – Binary Search Tree IteratorInorder traversal split across two methods, and that is the whole insight — the descend-left loop becomes the advance step and the stack becomes the object's state. Plus the amortised argument that makes next() O(1) on average when a single call can clearly do O(h) work.
- LeetCode 170 – Two Sum III – Data Structure DesignNot an algorithms problem — a question about which operation gets called more often. Two designs with opposite costs, and the answer the interviewer wants is the sentence that chooses between them. Plus why it must count rather than use a set: find(4) after one add(2) is false.
- LeetCode 169 – Majority ElementBoyer-Moore voting is four lines that look like they cannot be correct, and the counting argument is short enough to give out loud: every disagreement cancels a pair, and a strict majority cannot be exhausted. The algorithm does not find the majority — it eliminates everything that cannot be it.
- LeetCode 168 – Excel Sheet Column TitleLooks like base-26 and is not: Excel's digits run A to Z representing 1 to 26, with no symbol for zero. That single missing digit is the entire problem, the fix is one decrement inside the loop, and 26 vs 27 is where every wrong solution shows itself.
- LeetCode 160 – Intersection of Two Linked ListsAn O(1)-space solution that looks like sleight of hand: when a pointer runs off one list, restart it on the other. The trick is two lines and the reason is one equation — a + c + b = b + c + a, so both arrive together. Switch on null, not on the last node.
- LeetCode 159 – Longest Substring with At Most Two Distinct CharactersThe sliding window at its most reusable, and unlike Minimum Window Substring it generalises to k by changing one literal. The single bug it has: a count that reaches zero must be DELETED, not left sitting there, or the map size counts characters that have already left the window.
- LeetCode 158 – Read N Characters Given Read4 II – Call Multiple TimesThe same API with one sentence changed, and that sentence changes the design rather than the code. Problem 157 discards the surplus from its last chunk; called twice, that surplus is lost data. Three fields of state, and you have written a buffered reader.
- LeetCode 157 – Read N Characters Given Read4An API-adaptation problem: a primitive that reads in 4-character chunks, a caller that wants exactly n. A short read means end of file, and both limits need guarding — writing past n is a buffer overrun into the caller's memory, not a wrong answer.
- LeetCode 156 – Binary Tree Upside DownPure pointer surgery with no search and no complexity to argue about. The whole problem is doing four assignments in an order that does not destroy what the next one needs — null out root.left before reading it and the subtree is gone. Both pointers must be nulled, not just one.
- LeetCode 152 – Maximum Product SubarrayKadane with multiplication, and the change is bigger than it looks: a large negative is not a bad prefix, it is a latent good one waiting for another negative. Carry the minimum as well as the maximum, and watch the assignment order — curMin needs the OLD curMax.
- LeetCode 151 – Reverse Words in a StringOne line in Python and a real exercise in Java, which is what makes it a good question. Reverse the whole string, then reverse each word back — the first pass fixes the order and breaks the spelling, the second fixes the spelling without moving anything. The spaces are the fiddly part.
- LeetCode 149 – Max Points on a LineA Hard problem whose algorithm is trivial and whose difficulty is entirely how you represent a slope. Floating point is unsound as a hash key and fails silently on large coordinates; an unreduced pair splits equal slopes; a reduced pair without a sign convention splits opposite directions.
- LeetCode 146 – LRU CacheThe most common design question on the list, and a design question rather than an algorithms one: no single structure does the job, and two together give O(1) everywhere. Why the list must be doubly linked, why sentinels delete a dozen branches, and why the node has to store its own key.
- LeetCode 145 – Binary Tree Postorder TraversalThe hardest traversal to write iteratively, and the standard answer avoids writing it at all: postorder reversed is node-right-left, which is preorder with the children swapped. Two lines changed and every awkwardness disappears — plus what it costs when you genuinely need it bottom-up.
- LeetCode 144 – Binary Tree Preorder TraversalThe easiest of the three traversals to write iteratively, and worth doing right after inorder because the contrast explains why: a preorder node is emitted the moment you arrive, so there is nothing to come back for. Push right before left, since a stack reverses what you give it.
- LeetCode 142 – Linked List Cycle IIReset one pointer to the head after they meet and both walk to the cycle's entrance. It looks like a coincidence and it is four lines of algebra: t = k*c - m. Deriving that is what separates recall from understanding — and it is the same trick behind Find the Duplicate Number.
- LeetCode 141 – Linked List CycleWhere Floyd's tortoise and hare earns its keep. The hash set is correct and obvious; the two-pointer version is constant space and rests on an argument you should be able to give, because "they meet eventually" is an assertion. The gap closes by exactly one per step, so it must pass through zero.
- LeetCode 139 – Word BreakWhere greedy string matching visibly fails and DP visibly saves it, with a counterexample small enough for a whiteboard. The reframing is the usual one — can the first i characters be built? — and dp[0] = true is doing real work. Plus why the dictionary must be a set.
- LeetCode 138 – Copy List with Random PointerClone Graph in a linked list's clothes: you cannot point at a node that does not exist yet, and random pointers point forwards. The map answer is short and correct. The O(1) answer stores the mapping inside the list itself by weaving each copy in after its original.
- LeetCode 136 – Single NumberThe problem that teaches XOR as a tool rather than a curiosity. Linear time and constant space rule out both obvious answers, and what is left is a one-line fold — which looks like magic until you name the three properties, including the commutativity that handles unsorted input.
- LeetCode 134 – Gas StationEight lines of code and a proof that is the entire interview. Why a non-negative total guarantees a solution exists, and why running dry at station i rules out every start from the current candidate through i — which is what makes it one pass instead of quadratic. The reset is Kadane, read differently.
- LeetCode 133 – Clone GraphThe traversal is the easy part. One hash map does two jobs — visited set and old-to-new mapping — and one line decides whether the function terminates at all: register the clone BEFORE recursing, or an undirected edge sends you straight back and never bottoms out.
- LeetCode 131 – Palindrome PartitioningBacktracking with a filter, and the cleanest illustration of where the recording happens: Subsets records at every node, this records only when the string is fully consumed. Get that wrong and partial partitions land in the output. Plus the precomputed palindrome table for the repeated work.
- LeetCode 125 – Valid PalindromeA two-pointer warm-up with one nasty trap: '0' and 'P' differ by exactly 32, so the popular case-insensitive shortcut says they match. The 32 gap is a fact about letters, and it stops meaning anything the moment digits are in scope. Also why each skip loop needs its own bound.
- LeetCode 124 – Binary Tree Maximum Path SumThe hardest version of the pattern this track has been building toward since Diameter: the recursion returns one quantity and records another. A path that uses both children cannot also reach the parent, which is the geometric fact behind the whole solution. Twelve lines, and no debugging helps if the two are confused.
- LeetCode 122 – Best Time to Buy and Sell Stock IIA rare case where removing a constraint makes the problem easier. Every profit is a sum of consecutive daily deltas, so take every positive one — and that derivation is what turns a greedy that looks like cheating into one that is obviously optimal. Plus the two-state form that survives fees, cooldowns and caps.
- LeetCode 121 – Best Time to Buy and Sell StockWorth more than its Easy tag, because the reframing it teaches is the one behind Kadane's algorithm and most 1-D DP. The brute force asks which pair of days is best; the linear solution asks what the best buy was if I sell today — and that has a one-variable answer. Why a falling market returns 0, and why this is Maximum Subarray in disguise.
- LeetCode 119 – Pascal's Triangle IIOne row, in O(k) space, which turns a warm-up into a real exercise in updating an array without destroying what you are about to read. Sweep right to left so the stale values survive — the same rule that separates 0/1 knapsack from unbounded, and the question is always which values the cell needs.
- LeetCode 118 – Pascal's TriangleThe gentlest bottom-up DP there is, and on the list as the setup for its follow-up. The edges are where the rule runs out of inputs rather than a special case bolted on, the output size IS the complexity so there is nothing to optimise — which is exactly why problem 119 asks for one row.
- LeetCode 114 – Flatten Binary Tree to Linked ListThe best problem on the list for the idea that pointer surgery can replace a data structure. Three solutions using O(n), O(h) and O(1) space — the last one splices the right subtree onto the left subtree's rightmost node, which is Morris threading kept rather than undone.
- LeetCode 112 – Path SumA three-line recursion containing a base case almost everyone writes wrong. Returning targetSum == 0 at a null accepts a path that stops at a non-leaf, and it passes the examples while failing on a four-node tree. Null is not a leaf. Plus why negative values kill the obvious pruning.
- LeetCode 111 – Minimum Depth of Binary TreeThe payoff for the trap set in problem 104: swapping max for min is wrong, because a node with one child is not a leaf and its missing side still reports zero. A missing child is infinity, not zero — and this is where BFS genuinely beats DFS, since it can stop at the first leaf.
- LeetCode 110 – Balanced Binary TreeA correct answer most people write and a better one the same length. The gap is one idea: make the return value carry two things. Heights are never negative, so -1 is a free sentinel for "unbalanced" — and that turns O(n log n) into O(n) with an early exit for free.
- LeetCode 105 – Construct Binary Tree from Preorder and Inorder TraversalThe problem that makes traversal orders click: preorder tells you the root, inorder tells you the split. Why the hash map is what makes it O(n), why slicing arrays quietly reintroduces the quadratic, why the left subtree must be built first, and why preorder plus postorder is not enough.
- LeetCode 104 – Maximum Depth of Binary TreeThree lines, and the smallest problem where the recursive shape of tree algorithms is visible. The real value is the trap it sets up: swapping max for min does NOT give minimum depth, because a node with one child is not a leaf and the null branch reports a path ending in mid-air.
- LeetCode 103 – Binary Tree Zigzag Level Order TraversalLevel order with the direction alternating, and the answer people reach for first — reversing the queue — is the one that breaks. How you traverse and how you report are different things, and modifying the traversal to change the output is a category error.
- LeetCode 102 – Binary Tree Level Order TraversalThe problem that teaches BFS on trees, and everything depends on one line: capture the queue's size BEFORE draining the level. Looping on queue.size() re-evaluates a moving target and takes a meaningless slice. Also why deque beats a list in Python by a whole factor of n.
- LeetCode 101 – Symmetric TreeSame Tree with two characters changed, and worth doing straight after it for exactly that reason. Symmetry is a property of a PAIR of nodes, so the recursion takes two arguments and crosses them. Plus the inorder-palindrome shortcut, and the tree that kills it.
- LeetCode 100 – Same TreeThe smallest possible tree recursion, and the template the harder tree problems are written against. Three base cases and one recursive step — and the ORDER of those base cases is the only thing that can go wrong, because each one protects the next from a null dereference.
- LeetCode 98 – Validate Binary Search TreeThe most famous wrong answer on the list: checking each node against its immediate children is not the BST property. A node's bounds come from every ancestor and narrow on the way down. Plus the Integer.MIN_VALUE sentinel trap, and the inorder alternative that generalises to Recover BST.
- LeetCode 94 – Binary Tree Inorder TraversalFour lines recursively, which is why the statement ends with "could you do it iteratively?" — the recursion is the warm-up and the explicit stack is the question. Why the loop needs both halves of its condition, why no visited flag is required, and Morris traversal for when O(1) space is asked for.
- LeetCode 91 – Decode WaysClimbing Stairs with the steps made conditional, and that one change means most wrong answers come from a single character: '0'. The recurrence takes a minute; the zeros take the rest of the interview. Why the two-digit gate needs a LOWER bound of 10, and why ways(0) must be 1.
- LeetCode 88 – Merge Sorted ArrayTagged Easy, with one idea worth more than most Mediums: when you write into an array you are also reading, go backwards. The trailing zeros are reserved space rather than data, forwards clobbers values it has not consumed, and looping on nums2 alone is what makes the remainder handle itself.
- LeetCode 83 – Remove Duplicates from Sorted ListFive lines with one bug in them that nearly everyone writes first: advancing after a deletion skips the node that just became the successor, and only three equal values in a row exposes it. Also the cleanest place to learn when a linked list needs a dummy head — exactly when the head itself can be removed.
- LeetCode 81 – Search in Rotated Sorted Array IIProblem 33 with duplicates, which looks like a one-line change and is not. Two arrays with the pivot in different halves can present identical evidence at every point the algorithm may look, so no decision is right for both. The worst case is O(n) — and that bound is on the problem, not on your approach.
- LeetCode 78 – SubsetsThe cleanest backtracking problem there is, with one structural difference worth spotting: every node of the recursion tree is an answer, not just the leaves, so the base case disappears. Plus the two bugs — i + 1 rather than start + 1, and the copy without which all 2^n entries alias one list.
- LeetCode 76 – Minimum Window SubstringThe hardest sliding window on most lists, and the difficulty is not the window — it is knowing when it is valid without recounting. One integer does it, the counts are allowed to go negative because the sign carries the surplus, and t = "aa" is the case that separates working from nearly working.
- LeetCode 72 – Edit DistanceThe two-dimensional DP problem — if you get one 2-D table fluent, make it this one. Why dp[i][j] must be defined over prefix lengths rather than indices, why the extra row and column remove every edge case, and how to work out which neighbour is the insert instead of guessing.
- LeetCode 71 – Simplify PathA stack problem disguised as string manipulation, and the stack is not an optimisation — it is the only structure that models what .. means. Splitting on / handles doubled and trailing slashes for free, popping an empty stack must be a no-op, and "..." is an ordinary filename.
- LeetCode 70 – Climbing StairsFibonacci wearing a hard hat, and the smallest problem where the recursion-to-DP conversation happens naturally. Recognising the sequence is nice; being able to say why it is Fibonacci is the answer, because the recurrence is what survives when the step sizes become arbitrary and it turns into Coin Change.
- LeetCode 69 – Sqrt(x)A binary search problem that never mentions a sorted array — binary search is for any monotonic predicate, and spotting one with no array in sight is the lesson. Plus the overflow that is really the point: mid * mid goes negative near MAX_VALUE and the search silently walks the wrong way.
- LeetCode 68 – Text JustificationNo algorithmic difficulty and one of the highest failure rates on the list, because the spacing rules have four interacting cases and each is a silent off-by-one. Split packing from padding before typing, collapse the four cases into two, and remember the single-word line where gaps would be zero.
- LeetCode 67 – Add BinaryLooks like string manipulation, is really about carries — and the parse-to-integer answer everyone writes first is exactly what the 10,000-character constraint rules out. Why the carry belongs in the loop condition, why you build and reverse instead of prepending, and XOR and AND as sum-without-carry and carry.
- LeetCode 65 – Valid NumberNot an algorithms problem at all — it tests whether you can pin down an ambiguous spec with questions and turn it into code that does not sprawl. Three flags and one pass beat the finite-state machine, and resetting seenDigit on e is the single line that rejects 1e while accepting 3e+7.
- LeetCode 64 – Minimum Path SumSame table, one operator changed, and with it the entire class of problem. Building the grid where the greedy loses instead of just claiming it does, why a missing neighbour is infinity here when it was zero in the counting version, and why Integer.MAX_VALUE as the sentinel overflows into a path through the wall.
- LeetCode 63 – Unique Paths IIUnique Paths with obstacles: the recurrence is unchanged, one guard goes in front of it. An obstacle means zero paths, and zeros propagate on their own with no unreachable-region detection. The trap is the first row and column, where one obstacle cuts off everything after it.
- LeetCode 62 – Unique PathsThe cleanest introduction to grid DP there is, and worth doing carefully because the next two problems are this one with a single detail changed. Deriving the recurrence from what was the last move, compressing the table to one row and why the sweep direction makes that work, and why the combinatorial closed form is a footnote.
- LeetCode 58 – Length of Last WordA warm-up, and on the list because it is one — easy problems are where interviewers watch how you write rather than whether you can. split()[-1] is correct and allocates the whole string to read one word. Scan backwards instead: O(1) space, and end - i needs no plus one.
- LeetCode 57 – Insert IntervalThe list arrives sorted and non-overlapping, and re-sorting it throws away the precondition the problem went out of its way to give you. Three sequential loops sharing one index and no if statements, why absorbing needs a min as well as a max, and why the binary-search refinement does not change the complexity.
- LeetCode 56 – Merge IntervalsThe gateway to every interval problem, carried almost entirely by one decision: sort by start. Why that reduces overlap to a single comparison against the last output, why the merged end must be a max, why a[0] - b[0] as a comparator is a production bug, and when to sort by end instead.
- LeetCode 55 – Jump GameA greedy problem that spends most of its time disguised as dynamic programming. nums[i] is a maximum, not an exact jump, which makes the reachable set a prefix with no holes — and that is the justification the greedy needs. One variable replaces the whole DP table, plus the backward version for when you are asked to flip it.
- LeetCode 53 – Maximum SubarrayThe smallest problem that is genuinely dynamic programming, and almost everyone gets it nearly right then fails on an all-negative array. Deriving Kadane rather than recalling it, why best = 0 is the near-miss, keeping best and endingHere distinct, and the follow-up that asks where the subarray actually starts.
- LeetCode 52 – N-Queens IIThe same search asked for a count instead of the boards, and calling problem 51 and returning size() is exactly the answer it is designed to catch. Marking row - col and row + col makes the legality test O(1), the undo becomes mandatory, and the bitmask version is there if you are asked to go faster.
- LeetCode 51 – N-QueensThe problem people point at when they say backtracking, and it collapses once you see that every row holds exactly one queen — the board stops being a grid and becomes an int[n]. Both diagonals in one test, why no row check is needed, and why this version can skip the undo when the next one cannot.
- LeetCode 49 – Group AnagramsA hashing problem wearing a string problem's clothes. Find something identical for anagrams and different for everything else, then group by it. Sorting each word works; counting letters is better. And the separator everyone forgets — without it a word with 1 a and 11 b's collides with one that has 11 a's and 1 b.
- LeetCode 47 – Permutations IIPermutations with duplicates, and the extra line is a different extra line from the one Combination Sum II uses — which catches people who think they already learned this trick. With no start index, used[] is the only signal of depth, so the rule becomes !used[i-1]. All three de-duplication rules compared side by side.
- LeetCode 46 – PermutationsThe reference implementation of backtracking, and its value is the contrast with the combination problems. There a start index stops the same set appearing in different orders; here the different orders are the answer, so start disappears and used[] takes its job. Undo both pieces of state, or you get one permutation and then nothing.
- LeetCode 43 – Multiply StringsLong multiplication as you learned it at school and then forgot. It hinges on one piece of index arithmetic — the product of digits i and j lands at i + j + 1, carrying into i + j — which is worth deriving rather than memorising. Why the result needs exactly m + n slots, and why an intermediate slot going above 9 is harmless.
- LeetCode 42 – Trapping Rain WaterOne of the most-asked Hard problems, and it defeats people because they try to find the puddles. Do not. Ask how deep the water is above one column and the answer is one line: min(maxLeft, maxRight) − height. Why two pointers can decide with half the information, and the line ordering that silently returns a number slightly too small.
- LeetCode 41 – First Missing PositiveHard because of its constraints, not its question — a hash set solves it instantly, and O(1) space forbids one. Everything follows from a single observation: with n elements the answer is always in [1, n + 1], so every other value is noise. Cyclic sort uses the array as its own hash table, and the nested loop really is O(n).
- LeetCode 40 – Combination Sum IICombination Sum with two changes: each element used once, and the input may contain duplicates. The first is one character; the second is one line — and `i > start` rather than `i > 0` is the most misunderstood condition in the backtracking family. Getting it wrong does not duplicate answers, it loses them, which is far harder to notice.
- LeetCode 39 – Combination SumThe backtracking template with one twist: candidates may be reused without limit, which changes exactly one character in the recursive call. Why recursing from i rather than i + 1 is the whole difference, how the start index makes results unique structurally instead of by filtering, and why all-positive candidates are what guarantee the recursion terminates.
- LeetCode 36 – Valid SudokuNo algorithm at all — a bookkeeping problem. Rows, columns and all nine boxes can be checked in a single pass, and the only interesting line is the formula mapping a cell to its box: (row / 3) * 3 + col / 3. Encoding three facts per cell into one set, why valid is not the same as solvable, and the bitmask version for when you are asked to drop the hashing.
- LeetCode 34 – Find First and Last Position of Element in Sorted ArrayPlain binary search finds an occurrence; this wants the first and the last, and expanding outwards from a hit is O(n) the moment the array is all one value. The clean answer is one primitive — lower bound — called twice, with target + 1 giving the second answer. Why the window is half-open, and why removing the equality test removes the bugs.
- LeetCode 33 – Search in Rotated Sorted ArrayA rotated array is not sorted, so binary search should not work on it. It does, because however you cut it in half at least one half is properly sorted — and telling which is a single comparison. Why that comparison needs <= and not <, the overflow-safe midpoint, and why the duplicates variant provably degrades to O(n).
- LeetCode 31 – Next PermutationA problem you either see or you do not — no data structure, no recursion, just three passes in the right order. It starts from one observation: a descending suffix is already maximal, so the change has to reach further left than it goes. Finding the pivot, why scanning from the right finds the smallest larger value for free, and why reversing beats sorting the suffix.
- LeetCode 28 – Implement strStr()Reimplement indexOf. The honest answer to 'do I need to write KMP?' is almost always no — the interviewer wants a clean nested loop with correct bounds, and the bounds are the entire problem. Why i <= n - m is not a typo, how it handles a too-long needle for free, why not to allocate a substring per position, and how to raise KMP without walking into it.
- LeetCode 23 – Merge k Sorted ListsMerging two lists is solved; the question is in what order you merge k of them, and the obvious order costs a factor of k. Where that extra factor comes from, why pairwise merging gets it to O(N log k), and an honest comparison of divide-and-conquer against a min-heap — same time, different space, and only one of them survives the streaming follow-up.
- LeetCode 22 – Generate ParenthesesThe problem that teaches constrained backtracking. The lazy solution builds all 4^n bracket strings and filters; the intended one never builds an invalid string, because two small rules make it impossible. Why close < open is sufficient — not just true — the undo step everyone forgets, and why the output being Catalan-sized bounds any possible solution.
- LeetCode 21 – Merge Two Sorted ListsThe merge step of merge sort, isolated. Worth writing carefully rather than quickly, because Merge k Sorted Lists calls it and so does sorting a linked list. The part people over-engineer: splice the remaining list on in a single assignment instead of looping it out. Why the space is O(1), and why <= rather than < is the detail that shows you were thinking.
- LeetCode 20 – Valid ParenthesesThe canonical 'you should have reached for a stack' problem. Nesting means the thing you must close next is the thing you opened most recently. The trick that shortens the code: push the closer you expect, not the opener, so the check becomes one equality test. Three failure modes, three checks — and why ArrayDeque beats the legacy Stack.
- LeetCode 19 – Remove Nth Node From End of ListYou cannot walk a singly linked list backwards, so the nth node from the end has to be found from the front. Two pointers held a fixed distance apart do it in one pass — but the gap is n + 1, not n, because unlinking a node needs the node before it. Why the dummy head is not optional here, and an honest note on what 'one pass' actually buys.
- LeetCode 15 – 3SumThe problem that teaches sort-then-two-pointers. The algorithm is the easy half; the half that decides whether you pass is de-duplication, and there are two separate places a duplicate gets in. Why sorting buys three things at once, why the anchor skip must compare backwards, and why no solution can beat O(n²) when the output itself can hold that many triplets.
- LeetCode 14 – Longest Common PrefixA five-minute problem whose only real content is the edge cases. Scanning vertically — one character position down the whole array before moving right — is shorter than the horizontal version, exits at the first mismatched column, and makes the bounds check handle both short strings and empty ones in a single line. Plus the sorting trick, and why it is the worse answer.
- LeetCode 13 – Roman to IntegerThe inverse of Integer to Roman, and the trick that solved that one does not transfer. Going this way, all six subtractive pairs are handled by a single comparison: if a symbol is smaller than the one after it, subtract it. No table of pairs, no lookahead bookkeeping, and you never need to recognise CM as a unit. Java and Python, plus why not to rebuild a HashMap on every call.
- LeetCode 12 – Integer to RomanIt looks like it needs a pile of special cases — four is IV, nine is IX, forty is XL. It does not. Put the six subtractive pairs into the symbol table as if they were symbols in their own right, and the problem collapses into a plain greedy loop with no branches at all. Why greedy is provably safe once the table is descending, and why String += is the wrong way to build the answer.
- LeetCode 10 – Regular Expression MatchingThe first genuinely Hard problem on the list, and the difficulty is not the code. '*' is not a character — it is a modifier on the character to its left, so x* is one indivisible unit with two branches you must both try. The recursion, why it is exponential, the memo that needs Boolean rather than boolean, the bottom-up table, and the first row that is not all false.
- LeetCode 9 – Palindrome NumberTrivial with toString, which is why the follow-up — solve it without converting to a string — is the real question. Reversing only half the number cannot overflow, unlike reversing all of it. The loop that stops at the midpoint, the odd-digit case that needs reversed / 10, and the trailing-zero guard that makes 10 return false instead of true.
- LeetCode 8 – String to Integer (atoi)Almost no algorithm — a specification-reading exercise dressed as a coding problem, asked because sloppy engineers write parsers that eat production data. The rule that catches people is that atoi clamps to INT_MIN/INT_MAX where Reverse Integer returns zero. Four ordered steps, overflow detected before it happens, and the two Python traps: str.isdigit() and unbounded integers.
- LeetCode 7 – Reverse IntegerTagged Easy, and it is not quite. Reversing the digits takes four lines; the problem is detecting 32-bit overflow without being allowed a 64-bit type. Two ways to check — undo the step, or rearrange the inequality — plus why Java's truncating % carries the sign for free, why Math.abs breaks on Integer.MIN_VALUE, and why Python needs the opposite care because its integers never overflow.
- LeetCode 5 – Longest Palindromic SubstringCounting substrings is O(n³) and the DP table costs O(n²) memory. Neither is the answer you want: a string has only 2n − 1 centres, and expanding around each one is O(n²) time in O(1) space and about fifteen lines. The even-length centre everyone forgets, the hi − lo − 1 off-by-one, the interval DP for when you need it, and where Manacher's linear algorithm fits.
- LeetCode 2 – Add Two NumbersLong addition wearing a linked list costume. Reverse digit order is a gift, not an obstacle — it points the lists the same way the carry travels. The dummy head that removes the first-node special case, the carry in the loop condition that gives 999 + 1 its fourth node, and why converting to an integer overflows on the real test cases. Java and Python, plus the forward-order follow-up.
- LeetCode 1 – Two SumThe first problem on LeetCode, and still the most common phone-screen warm-up. It is not a test of whether you can find two numbers — it is a test of whether you reach for a hash map the moment you catch yourself writing a nested loop. One pass, look up before you insert, and the target = 2 × nums[i] case that lets an element pair with itself. Java and Python, plus the sorted two-pointer variant that 3Sum is built on.
- Max Subset Sum No AdjacentWrite a function that takes in an array of positive integers and returns the maximum sum of non-adjacent elements in the array. If the input array is empty, the function should return 0. Sample input [75, 105, 120, 75, 90, 135] Sample output 330 = 75 + 120 + 135 Solution Time Complexity: O(n) Space…
- Minimal Waiting TimeYou’re given a non-empty array of positive integers representing the amounts of time that specific queries take to execute. Only one query can be executed at a time, but the queries can be executed in any order. A query’s waiting time is defined as the amount of time that it must wait before its…
- Nth FibonacciThe Fibonacci sequence is defined as follows: the first number of the sequence is 0, the second number is 1, and the nth number is the sum of the (n – 1)th and (n – 2)th numbers. Write a function that takes in an integer n and returns the nth Fibonacci number. I have a […]
- Palindrome CheckWrite a function that takes in a non-empty string and that returns a boolean representing whether the string is a palindrome. A palindrome is defined as a string that’s written the same forward and backward. Note that single-character strings are palindromes. Solution Loop through half of the…
- Binary SearchWrite a function that takes in a sorted array of integers as well as a target integer. The function should use the Binary Search algorithm to determine if the target integer is contained in the array and should return its index if it is, otherwise -1. I have a solution here.
- Quick SortWrite a function that takes in an array of integers and returns a sorted version of that array. Use the Quick Sort algorithm to sort the array. I have a solution here.
- Three Number SumWhere the two-pointer technique stops being a curiosity and becomes the tool — sorting buys three separate things at once and no hash-based approach gets all three. Why both pointers move after a hit, why the result should be List<List<Integer>> rather than List<Integer[]>, and exactly what changes when duplicates are allowed.
- Two Number SumThree reasonable answers with genuinely different trade-offs, and laying all three out before choosing is the actual skill being tested. Why the inner loop starts at x + 1 rather than 0, why you must check the set before inserting or an element pairs with itself, and why sorting quietly reorders the caller's array. Java and Python, plus the indices variant.
- Fizzbuzz
- Recursion in Coding InterviewsMost people can explain what recursion is and still freeze when a problem needs it under time pressure. The three questions that turn a blank page into a fill-in-the-blanks exercise, the leap of faith that stops you tracing calls in your head, when recursion is the wrong tool, and how to reason about the cost of a branching search.
- Class PhotosIt’s photo day at the local school, and you’re the photographer assigned to take class photos. The class that you’ll be photographing has an even number of students, and all these students are wearing red or blue shirts. In fact, exactly half of the class is wearing red shirts, and the other half…