Array & String

Work through examples, try the reasoning yourself, then put it into practice.

View Slides

Lesson

31 min read

Array & String Foundations (Interview 150)

Reader guide and study workflow · Complete course map

A sensor buffer contains [9,4,9,7,4]; value 9 means an unusable reading. A caller needs the valid readings in their original order, using the same storage. Before choosing an algorithm, write the required result: logical length 3, prefix [4,7,4], and no requirement for the last two slots.

Derive a safe write

An easy specification is to copy valid readings into a fresh list. That establishes what correctness means, but uses another buffer. A second idea deletes one bad reading and shifts the suffix left each time; with many deletions, the same value may move repeatedly, leading to quadratic work.

What information from the copy-based solution must survive? Only how many readings have been accepted. Let read inspect the next original position and write mark the next output slot. Rejecting 9 moves read alone. Accepting 4 writes it at write, then advances both. The key safety claim is write <= read: an accepted value never overwrites input that has not been inspected. This derives the two indices from the data dependency.

On this input, accepting the first 4 temporarily produces [4,4,9,7,4]. That array looks wrong if you inspect all five slots. It is correct if you inspect the stated region: the accepted prefix is [4], and the later input remains available. This is why the contract must come before the loop.

Now change the requirement: if survivor order did not matter, swapping a rejected reading with the final unread element would be another viable strategy. If instead two sorted arrays must be merged into shared storage, forward writes can destroy needed values. The next workshop develops how the direction and the proof change with the contract.

Prerequisites and readiness

You should be able to index a Go slice, distinguish its length from capacity, and explain why assigning nums[i] changes shared backing storage. Before leaving this module, derive a safe write direction, prove a greedy discard, and separate an output prefix from an unspecified tail.

Reasoning workshop: protect unread information

Start with the contract, not the pattern name

Three similar-looking array tasks require different proofs. Stable removal constructs a prefix; merging constructs a suffix; rotation permutes the entire array. A sentence such as “everything before a pointer is correct” is useful only when it names the right region and says what “correct” means. For merge, the finalized region is after the write pointer. For removal, it is the original non-target subsequence, not merely any collection of survivors.

Write the regions before the loop. For stable removal at read position r, use kept | discarded/processed | unread, with boundaries w and r. The relationship w <= r is the safety argument: writes cannot reach tomorrow's input. The returned length is w; clearing the remaining tail would do extra work without fulfilling another part of the contract.

A worked overwrite trace

Merge valid prefix [2,4] and array [1,3] into [2,4,0,0].

Before the write Largest unread value Destination State after the write
i=1, j=1, w=3 4 index 3 [2,4,0,4]
i=0, j=1, w=2 3 index 2 [2,4,3,4]
i=0, j=0, w=1 2 index 1 [2,2,3,4]
i=-1, j=0, w=0 1 index 0 [1,2,3,4]

The intermediate array need not be sorted. Only the suffix after w is final. While the second array is nonempty, w=i+j+1>i; this inequality is why a write cannot destroy a needed first-array value. After the second array is exhausted, the unread first prefix is already in place. This proof gives the loop condition j >= 0, rather than guessing when pointers “meet.”

Greedy means a justified loss of choices

In Jump Game, every position in the reachable prefix can be reached because a jump may be shorter than its maximum length. Before using nums[i], establish i <= farthest. The array [1,0,100] is a useful adversary: the large jump is irrelevant because its index is unreachable. Updating farthest first would manufacture a path.

Jump Game II needs more state. For [2,3,1,1,4], the zero-jump layer ends at 0. After examining index 0, the one-jump layer ends at 2. Examining indices 1 and 2 extends the two-jump layer to 4. currentEnd is a committed layer boundary; farthest is the next layer under construction. A jump is charged when a whole layer is finished, not each time a larger reach appears. The final index is a destination, not a place from which another jump must be charged.

For Gas Station, a failed candidate s gives a stronger discard. If its first negative balance occurs at i, its balance on reaching a later start j in that segment was nonnegative. Starting afresh at j supplies zero initial fuel, so it has no more fuel available for the same remaining segment. It therefore also fails by i. All starts through i can be removed together. Total nonnegative balance proves existence, not uniqueness: gas [2,2], cost [1,1] has two valid starts. The provided scan deterministically keeps the first feasible candidate.

Two proof styles that are easy to confuse

Boyer-Moore uses cancellation. A balance of one does not mean the candidate occurred once; it means one unmatched vote remains after pairing unequal values. Its guarantee depends on a strict majority existing. Without that promise, an independent counting pass is required to validate the candidate.

Unlimited stock trading uses a telescoping sum. A rise from price 1 to 5 via 2 and 4 has differences 1, 2, and 1, which sum to the same profit 4. Collecting every positive adjacent difference attains an upper bound on any legal sequence of trades. A fee would invalidate this decomposition: several small rises could be worse than one long hold. The one-trade version instead keeps the cheapest earlier purchase and cannot reuse all rises independently.

Numeric and ownership checks

Use the declared 64-bit runner model when reasoning about large accumulated profits or gas balances. An int return type is not a promise of arbitrary-precision arithmetic. A function that is described as in-place must change the caller's slice elements; rebinding a local slice variable is not enough. Product Except Self is different: it creates a new result, leaves the input alone, and counts that result separately from auxiliary storage.

The empty product is one. Thus [7] produces [1]; [2,0,4] produces [0,8,0]; two zeros make every output zero. Derive these outcomes from the definition rather than treating zero as a special patch to a division-based algorithm.

Pattern reference

Use these summaries after deriving the state and the reason each update is safe. The patterns name decisions already justified above.

Pattern 1: Read/Write Compaction ("slow/fast")

Use when you must remove elements in-place or deduplicate without extra memory.

Invariant:

  • write points to the next position to fill with a valid element.
  • read scans every element exactly once.

Template:

write := 0
for read := 0; read < len(nums); read++ {
    if keep(nums[read]) {
        nums[write] = nums[read]
        write++
    }
}
return write

Used by:

  • Remove Element
  • Remove Duplicates from Sorted Array
  • Remove Duplicates from Sorted Array II

Common failures:

  • Forgetting that the return value is the new length, not a new slice.
  • Updating write even when the element is skipped.
  • Off-by-one when the array is empty.

Pattern 2: Two Pointers from Both Ends

Use when you can place elements at the end or compare symmetric positions.

Invariant:

  • The finalized region depends on the task: merge finalizes only a suffix.
  • A symmetric reversal finalizes both ends; do not apply that invariant unchanged to a merge.

Reversal skeleton (merge uses the three pointers shown in the workshop):

l, r := 0, len(nums)-1
for l < r {
    nums[l], nums[r] = nums[r], nums[l]
    l++
    r--
}

Used by:

  • Merge Sorted Array (merge from the end to avoid overwrite)
  • Rotate Array (via reverse or cycle method)

Common failures:

  • Overwriting values when merging from the front.
  • Forgetting to handle n=0 before k %= n, or confusing a Go slice's exclusive endpoint with an inclusive reversal-helper endpoint.

Pattern 3: Rotation via Reverse or Cycles

A rotation can be done in-place by reversing sections.

Reverse trick for right rotation by k:

  1. Reverse the entire array.
  2. Reverse the first k elements.
  3. Reverse the remaining n-k elements.

Why it works: the rightmost k elements move to the front, and their internal order is restored by the second reverse.

Used by:

  • Rotate Array

Common failures:

  • Forgetting k %= n.
  • Reversing in the wrong order.

Pattern 4: Single-Pass Greedy Scans

Some array problems are solved by scanning once while maintaining a best-so-far state.

Examples:

  • Best Time to Buy and Sell Stock: track the minimum price so far and compute max profit.
  • Jump Game: track the farthest reachable index and fail if i > farthest.

Invariant:

  • The tracked state always reflects the best possible result using elements up to i.

Common failures:

  • Using a future minimum as a past purchase. In the no-fee single-trade problem, updating the running minimum before computing profit is safe: it merely admits a zero-profit same-day candidate.
  • Returning too early without checking reachability.

Pattern 5: Counting and Selection

When you need a majority element or index-based selection, counts or buckets usually beat sorting.

Majority (Boyer-Moore):

  • Maintain a candidate and a count.
  • If count == 0, pick new candidate.
  • Increment or decrement based on equality.

H-Index:

  • With n papers, h cannot exceed n. Count each citation c in bucket min(c,n), then accumulate buckets from n down to 0. The first h whose accumulated count is at least h is the largest feasible threshold.

Common failures:

  • Forgetting that Boyer-Moore assumes a true majority exists.
  • Off-by-one in H-index comparisons.

Pattern 6: Prefix/Suffix Products

When the output at index i needs all elements except i, compute prefix and suffix products.

Invariant:

  • prefix[i] is the product of all elements before i.
  • suffix[i] is the product of all elements after i.

Used by:

  • Product of Array Except Self

Quick checks (when to use this module's patterns)

  • In-place edits required? Use read/write compaction or two pointers.
  • Need to move a block? Try reverse-based rotation.
  • Find max/min under a constraint? Try a single-pass greedy scan.
  • Exclude current element from aggregate? Try prefix/suffix.

Common pitfalls across the module

  • Off-by-one errors at the ends of the array.
  • Forgetting to handle len == 0 or k %= n.
  • Mutating the input but still returning a new slice.
  • Hidden O(n^2) behavior (nested loops) on large arrays.

Reconstruction lab

  1. Compaction: keep at most three copies of each value in a sorted slice. Which accepted-output position decides whether a new copy is legal?
  2. Rotation: split ABCDE into A=ABC and B=DE. Write the three intermediate block expressions for a right rotation by two.
  3. Greedy boundary: add a one-unit fee to every stock sale. Give an input where collecting each positive difference separately is no longer optimal.
Model answers

For the cap-three variant, accept when write < 3 or the new value differs from nums[write-3]. Sortedness makes equal kept values contiguous, so equality there proves three copies already exist.

Reversing AB gives reverse(B) reverse(A); reversing the first two elements gives B reverse(A); reversing the remainder gives BA. In concrete values: EDCBA, DECBA, DEABC.

For prices [1,2,3], two separate trades each earn 1 and each pay 1, giving zero. One trade from 1 to 3 pays one fee and earns 1. Transaction costs couple adjacent rises, so the no-fee greedy proof no longer applies.

Problems in this module

Interactive checkpoint

Open the Array & String quiz. The questions use exact, objectively gradeable answers. Work the reasoning drills above before opening their model answers.

Reader guide

Interview 150: A Guide to Independent Practice

This course contains 150 Go exercises in 22 modules. It is a curated selection, not a promise to match another platform’s list. The goal is to solve unfamiliar variations: define the state, explain why an update is safe, and diagnose a failing case. Completing 150 submissions and being able to do those things are different kinds of evidence.

Each problem provides substantial guidance. For an independent attempt, read through Constraints, predict an example, and sketch your state before opening Core idea, Algorithm, or the model answers. If you need help, reveal one step, apply it to a new input, and then continue with the explanation closed.

The reasoning loop

1. Make the question precise

Say what counts as an answer before choosing a data structure. Are two equal values two distinct occurrences? Does the caller care about order, mutation, or identity? Which input promise is available? Work one small example by hand and state what would make its answer wrong.

2. Build a simple correct model

Enumerate the possibilities or simulate the rules directly. Count the work at the largest stated size. A slow method can be the best explanation, a useful small-input test oracle, or a sufficient solution when the workload is small. Optimize a specific repeated operation rather than a vague feeling that the code is slow.

3. Derive what must be remembered

Ask which facts let you answer the next step without repeating old work. State precisely what each variable means. Challenge the proposed state: can two different histories look identical to it but require different answers? If so, it has discarded too much information. Establish the invariant, explain why each update preserves it, and show what makes the computation finish.

4. Try to break and adapt the argument

Construct a small counterexample to a tempting shortcut. Then change one requirement: duplicates, signed inputs, streamed updates, weighted edges, output order, or memory limits. Explain whether your state and proof survive. Only after that, rebuild the code with the explanation closed.

A worked reasoning notebook

A log stores daily net changes. Count the contiguous periods whose total equals 3. For [3,-1,-2,3], first list the valid zero-based intervals before reading further.

Start from the complete small model

The intervals are [0,0], [0,3], and [3,3]: three occurrences, even though two contain the same single value. Enumerating every start and extending its running sum checks all n(n+1)/2 intervals in O(n²) time and O(1) extra space. It is correct and useful for checking tiny cases.

A positive-only shrinking window is not justified here. For [2,-3,4] and a requested sum of 4, the unchanged left boundary sees running sums 2, -1, 3 and never reaches 4; the single-element interval [4] still qualifies. Negative changes can make removing a prefix increase the sum.

The repeated work is summing overlapping periods. Let P[j] be the total of the first j changes, with P[0]=0. A period [i,j) has total P[j]-P[i]. Rearranging the requested equality gives P[i]=P[j]-3: for this endpoint, we need the number of earlier prefixes with that value. A set cannot distinguish one matching start from several. This equation derives the frequency map; the topic name is not the reason for choosing it.

Prefix endpoint j P[j] Earlier value needed Earlier occurrences Total periods found
0, before processing 0 — Store one empty prefix 0
1 3 0 1 1
2 2 -1 0 1
3 0 -3 0 1
4 3 0 2 3

Before processing endpoint j, the map counts exactly P[0] through P[j-1]. Query first, then insert P[j]. This counts every valid interval at its unique right endpoint, never counts a future start, and excludes empty intervals when the target is zero. The scan finishes after n endpoints and uses expected O(n) time and O(n) extra space under expected constant-time map operations. An implementation must also bound prefix/subtraction/count arithmetic in its chosen numeric type.

Now attempt both changes without copying the table:

  1. For [2,-2,2,-2] and target 0, how many periods qualify? Show the map counts that contribute to the answer.
  2. If the question asks for the longest qualifying period instead of their count, should each prefix value remember its frequency, its first position, or its last position? Derive the choice from the new objective.
Transfer model answers
  1. Prefixes are 0,2,0,2,0. Query contributions are 0,1,1,2, giving 4 periods. Insert-before-query would count the current empty period as well, so the update order is part of correctness.
  2. Keep the earliest endpoint for each prefix value. For a fixed right endpoint j, length is j-i; the smallest valid i gives the longest period. Never overwrite that earlier index. Frequencies lose positions, while retaining only the latest index gives the shortest qualifying period ending here. Initialize prefix zero at endpoint 0. The count problem and longest-period problem use the same equation but require different remembered information.

This is a paper reasoning exercise connecting the course's map, window, and state-design ideas. The graded Minimum Size Subarray Sum task still promises positive inputs and asks a different question. Transfer means deriving the change, not silently changing that task's contract.

A useful rule

If a solution feels clever but not inevitable, slow down. The missing piece is usually one sentence:

Because this invariant is true, this move is safe.

Find that sentence and the topic becomes much less mechanical.

Use each part of the course deliberately

Each module has a lesson, a slide deck, a problem sequence, and an interactive checkpoint after that sequence. The slides ask for predictions; presenter notes contain the model answer and proof. Every problem has a reconstruction checkpoint with a model answer in a supported details block.

The Go starter is intentionally an unsolved learner scaffold, not a claimed complete implementation. Its declarations define the API that your implementation must satisfy; its comments pose a reasoning question. The separately stored Go reference is complete. Compile-only checks verify starter/test compatibility; passing solution tests is the learner’s task. Do not copy both starter and reference into the same Go package.

Use public tests while building the solution. Hidden-mode verification also includes public tests. The suites include examples, boundary checks, and independent brute-force or model-based checks. Some tasks also check mutation, restoration, or pointer identity, so a correct-looking return value may be insufficient. Tests are evidence across their cases, not proof of correctness on every possible input; the lesson proofs and explicit input contracts address the broader argument.

Quiz answers are exact-text graded after trimming and case normalization. Short questions therefore ask for a number, boolean, or similarly concise response. Longer explanations belong in the Markdown reasoning exercises. A quiz passes only when all its questions are correct, and every question includes an explanation.

A reconstruction session with a stopping rule

Read the input/output contract and predict the smallest nontrivial case. Write the state meaning, then make a three-column trace: state before, operation, state after. Explain why each discarded candidate cannot improve the answer. Implement, run public tests, and investigate the first mismatch by comparing the trace rather than adding an unexplained special case. Finally close the reference and reconstruct from the invariant. Stop the session when the reconstruction and a new counterexample test both work; record the still-confusing step rather than repeating solved examples.

Contract checks before optimization

Distinguish bytes from characters, output order from set membership, nil from an empty collection where callers care, value equality from node identity, and returned results from input mutation. The provided app targets 64-bit Go. Read each problem's Constraints and Contract precision together: numeric preconditions specify which mathematical results and intermediate values must fit the preserved API. Do not silently add modular arithmetic. An expression that will be discarded can still overflow if evaluated too early; a proof over mathematical integers must also justify the implementation's evaluation order.

Choose a starting point

The module list groups patterns; it is not a prerequisite lock. Read the module's preparation and outcomes before starting. If a preparation task is unfamiliar, use the route below, then return. If it is familiar, try a reconstruction prompt with its answer closed and proceed directly to practice.

If you cannot yet… Revisit Evidence that you can continue
Explain which slice region may be overwritten Array & String Trace a merge without destroying an unread value.
Justify moving a boundary Two Pointers Name the entire group of candidate pairs a move discards.
Follow node identity through mutation Linked List Draw the saved successor and every changed edge.
Give a recursive call a precise return meaning Binary Tree General Separate a child's extendable result from the overall answer.
Restore shared state after a recursive branch Backtracking Show that a second board-search attempt sees the original board. This is useful before Trie board search.
Define what one graph edge represents Graph BFS State legal neighbors, starting distance, and its unit.
Label the predecessor used by a compressed table 1D DP, then 2D DP Trace one update using old and new state labels before changing storage.

A route through all 22 modules

The order below makes dependencies explicit while keeping the existing module navigation. A route is guidance, not a prerequisite lock. Take one reconstruction prompt before deciding whether a module needs a full lesson or just practice.

Stage Modules Evidence to collect before moving on
Preserve and summarize a sequence Array & String, Hash Map, Two Pointers, Sliding Window Explain an overwrite boundary, choose a map key, and give a counterexample to a pointer move without its precondition.
Boundaries and pending work Matrix, Intervals, Stack + Monotonic, Binary Search Trace original versus updated state, endpoint equality, the event that resolves a stack entry, and a shrinking search interval.
Identity and recursive contracts Linked List, Binary Tree General, Binary Tree BFS, Binary Search Tree, Divide & Conquer Draw changed edges, state a recursive return contract, freeze one BFS level, and distinguish a local comparison from an ancestor constraint.
Reachability and choices Graph General, Graph BFS, Backtracking, Trie, Heap Define an edge and the complete search state; restore branch-local mutations; explain why a heap root is the next eligible or worst retained candidate. Study board backtracking before the trie's board search.
Representation and reused subproblems Bit Manipulation, Math, 1D DP, 2D DP State the numeric width/domain, justify an overflow-safe comparison, and label every compressed dependency as old or new before overwriting it.

For each exercise, keep a small manual record: attempted, solved with guidance, rebuilt independently, or retrieved later. Record the specific missed decision, not just the problem name. Move from guided to independent only after explaining the invariant and solving a fresh case with the explanation closed. Revisit one old exercise alongside new work; a remembered code listing is a cue to change the input or contract and explain what must change.

Recover from a missed checkpoint

Each checkpoint question names the concept it checks and links to a specific lesson section. Questions tied to a supported exercise also provide a practice link. A design extension, such as changing the trie's alphabet, may only have a lesson link because the Go exercise still requires lowercase ASCII.

Before retrying, write the mistaken assumption in one sentence, follow the review link, and trace a different input with the same failure. Implement or repair the related exercise with the explanation closed. A same-session perfect retry records a quiz pass; it does not demonstrate that you can retrieve the method later. The six questions per module sample important reasoning decisions, not every problem or boundary in that module.

A delayed mixed check

On a later session, attempt these without looking at their topic links or answers. For each, write the state, the relevant precondition, and the result or counterexample. These are manual retrieval exercises; the app does not schedule them or record their scores.

  1. Find the shortest contiguous subarray with sum at least 4 in [2,-3,4]. Does the usual positive-sum shrinking window work unchanged? Give the answer and explain what its running sum misses.

  2. Two tasks receive [1,3] and [3,5]. One merges closed intervals; the other removes the fewest intervals so that touching endpoints are compatible. Give the merged output and the removal count. Which equality changes meaning?

  3. A search has directed edges S→A of cost 10, S→B of cost 1, and B→A of cost 1. FIFO BFS first reaches A in one edge. Is that the minimum-cost route? State both costs and identify the missing precondition for using edge count as cost.

  4. A stream is 5,1,4,2, and you must retain its largest two occurrences. If the retained set is a min-heap, give its final values and root. Explain what gets discarded when 4 arrives and why 2 is later rejected.

  5. A list has distinct nodes A(4) → B(9) → C(4). Reverse only the first two nodes. Draw the result using node names, identify the suffix pointer that must be saved, and explain why a clone map keyed only by node value would fail.

  6. A binary tree has root 8, left child 3, right child 10, and node 3 has right child 9. Every parent-child comparison looks ordered. Is the whole tree a BST? State the violated bound and give its level-order rows.

  7. A 2×2 Game of Life board is [[1,0],[1,1]]. Give the next board under simultaneous updates. If bit 0 holds the old state and bit 1 holds the next state, what encoded value should the originally dead top-right cell hold before the final shift?

  8. An edit-distance row is being updated left to right for source prefix ca and target car. At the cell comparing the final a in the source with the final r in the target, the old diagonal is 1, old above is 2, and new left is 0. What value is stored, and which old value must be saved as the next cell's diagonal? Explain why the new left cannot replace that saved value.

Mixed-check model answers and review routes
  1. The answer is 1, from [4]. The running sums from the unchanged left boundary are 2, -1, and 3, so the positive-sum template never even enters its qualifying-window loop. Removing the negative prefix can increase the sum; positivity was the monotonicity precondition. For this small input, enumerate all intervals to verify the answer. The pack's minimum-size exercise promises positive values; supporting signed values requires a different algorithm. Review window preconditions.
  2. The merged union is [[1,5]]; the scheduling removal count is 0. Closed merging treats a shared endpoint as overlap, while this scheduling contract allows one job to start exactly when another ends. Copying one inequality between the tasks changes the answer. Review endpoint contracts.
  3. The direct route costs 10; S→B→A costs 2. BFS minimizes the number of edges. Equal positive edge costs are sufficient to turn that guarantee into a minimum-cost guarantee; unequal costs can make the objectives disagree, as they do here. This variation falls outside the pack's unweighted shortest-path template. Review distance modeling.
  4. The retained values are 4 and 5, with root 4. When 4 arrives, it replaces the smallest retained candidate, 1. The later 2 cannot improve either retained rank. The heap exposes the worst retained value so that a new candidate can be compared against the admission threshold. Review bounded heaps.
  5. The result is B → A → C. Save C before detaching or reversing the two-node segment, then reconnect A to C. A and C have equal values but different identities; a value-keyed clone map would collapse two nodes and cannot preserve their separate edges. Review pointer ownership.
  6. It is not a BST: 9 belongs to the root's left subtree and must be less than 8. Its level-order rows are [[8],[3,10],[9]]; traversal order alone does not establish the BST property. The recursive validator must carry ancestor bounds, not compare only immediate children. Review BST reasoning.
  7. The next board is [[1,1],[1,1]]. Each originally live cell has two live neighbors; the dead cell has three. Its encoding is binary 10, decimal 2: old state 0, next state 1. Reading bit 0 throughout the first pass prevents a newly born cell from changing its neighbors' counts. Review simultaneous state.
  8. Store 1 + min(1,2,0) = 1. Save the old above value, 2, for the next cell's diagonal; that next diagonal refers to the preceding row, whereas the new left belongs to the current row. Here the target ends at r, so there is no next cell, but the preservation rule is the same inside a longer row. Review compressed dependencies.

For each response, check three pieces separately: a correct result, an explicit state or boundary trace, and a justified precondition or discard. If only the result is correct, redo the reasoning before marking it ready. If a precondition is missing, revisit that concept and create a new counterexample. Record the missed concept and revisit it in a later session with fresh values.

Learner navigation

The app imports manifest-backed lessons, statements, slides, and quizzes; it does not expose arbitrary Markdown files as pages. The complete trie drills, model keys, practice bank, and mentor guide are therefore embedded in the Trie lesson. The complete divide-and-conquer workbook and answer key are embedded in that lesson. This companion and the authoritative course list are embedded in Array & String. Their original standalone files remain available in the ZIP for offline use.

Open the trie drills and answer key · Open the divide-and-conquer workbook

Authoritative course map

Top Interview 150 - Curated Problem List (Go Pack)

This is this repository’s curated 150-problem course, in the authoritative pack.json order. It is not a claim that the selection or ordering exactly matches an external platform’s current list.

1) Array & String (13)

  1. Merge Sorted Array
  2. Remove Element
  3. Remove Duplicates from Sorted Array
  4. Remove Duplicates from Sorted Array II
  5. Rotate Array
  6. Majority Element
  7. Best Time to Buy and Sell Stock
  8. Best Time to Buy and Sell Stock II
  9. Jump Game
  10. Jump Game II
  11. H-Index
  12. Product of Array Except Self
  13. Gas Station

Lesson · Interactive quiz

2) Two Pointers (7)

  1. Valid Palindrome
  2. Is Subsequence
  3. Two Sum II - Input Array Is Sorted
  4. Container With Most Water
  5. 3Sum
  6. Sort Colors
  7. Reverse String

Lesson · Interactive quiz

3) Sliding Window (7)

  1. Minimum Size Subarray Sum
  2. Longest Substring Without Repeating Characters
  3. Longest Repeating Character Replacement
  4. Permutation in String
  5. Find All Anagrams in a String
  6. Minimum Window Substring
  7. Substring with Concatenation of All Words

Lesson · Interactive quiz

4) Matrix (6)

  1. Valid Sudoku
  2. Spiral Matrix
  3. Rotate Image
  4. Set Matrix Zeroes
  5. Game of Life
  6. Diagonal Traverse

Lesson · Interactive quiz

5) Hash Map (8)

  1. Ransom Note
  2. Isomorphic Strings
  3. Word Pattern
  4. Valid Anagram
  5. Group Anagrams
  6. Two Sum
  7. Happy Number
  8. Longest Consecutive Sequence

Lesson · Interactive quiz

6) Intervals (6)

  1. Summary Ranges
  2. Merge Intervals
  3. Insert Interval
  4. Non-overlapping Intervals
  5. Minimum Number of Arrows to Burst Balloons
  6. Interval List Intersections

Lesson · Interactive quiz

7) Stack + Monotonic (7)

  1. Valid Parentheses
  2. Simplify Path
  3. Min Stack
  4. Evaluate Reverse Polish Notation
  5. Daily Temperatures
  6. Largest Rectangle in Histogram
  7. Basic Calculator

Lesson · Interactive quiz

8) Linked List (10)

  1. Linked List Cycle
  2. Linked List Cycle II
  3. Add Two Numbers
  4. Merge Two Sorted Lists
  5. Copy List with Random Pointer
  6. Reverse Linked List
  7. Reverse Linked List II
  8. Reverse Nodes in k-Group
  9. Remove Nth Node From End of List
  10. LRU Cache

Lesson · Interactive quiz

9) Binary Tree General (10)

  1. Maximum Depth of Binary Tree
  2. Same Tree
  3. Invert Binary Tree
  4. Symmetric Tree
  5. Construct Binary Tree from Preorder and Inorder Traversal
  6. Construct Binary Tree from Inorder and Postorder Traversal
  7. Path Sum
  8. Sum Root to Leaf Numbers
  9. Binary Tree Maximum Path Sum
  10. Lowest Common Ancestor of a Binary Tree

Lesson · Interactive quiz

10) Binary Tree BFS (5)

  1. Binary Tree Level Order Traversal
  2. Binary Tree Zigzag Level Order Traversal
  3. Binary Tree Right Side View
  4. Average of Levels in Binary Tree
  5. Populating Next Right Pointers in Each Node II

Lesson · Interactive quiz

11) Binary Search Tree (4)

  1. Validate Binary Search Tree
  2. Kth Smallest Element in a BST
  3. BST Iterator
  4. Minimum Absolute Difference in BST

Lesson · Interactive quiz

12) Graph General (7)

  1. Number of Islands
  2. Surrounded Regions
  3. Clone Graph
  4. Evaluate Division
  5. Course Schedule
  6. Course Schedule II
  7. Redundant Connection

Lesson · Interactive quiz

13) Graph BFS (5)

  1. Word Ladder
  2. Snakes and Ladders
  3. Minimum Genetic Mutation
  4. Rotting Oranges
  5. Shortest Path in Binary Matrix

Lesson · Interactive quiz

14) Trie (4)

  1. Implement Trie (Prefix Tree)
  2. Design Add and Search Words Data Structure
  3. Word Search II
  4. Replace Words

Lesson · Interactive quiz

15) Backtracking (7)

  1. Letter Combinations of a Phone Number
  2. Combinations
  3. Permutations
  4. Combination Sum
  5. Generate Parentheses
  6. N-Queens II
  7. Word Search

Lesson · Interactive quiz

16) Divide & Conquer (4)

  1. Convert Sorted Array to Binary Search Tree
  2. Sort List
  3. Merge k Sorted Lists
  4. Construct Quad Tree

Lesson · Interactive quiz

17) Binary Search (7)

  1. Search Insert Position
  2. Search a 2D Matrix
  3. Find Peak Element
  4. Search in Rotated Sorted Array
  5. Find First and Last Position of Element in Sorted Array
  6. Find Minimum in Rotated Sorted Array
  7. Median of Two Sorted Arrays

Lesson · Interactive quiz

18) Heap / Priority Queue (5)

  1. Kth Largest Element in an Array
  2. Top K Frequent Elements
  3. Find K Pairs with Smallest Sums
  4. Find Median from Data Stream
  5. IPO

Lesson · Interactive quiz

19) Bit Manipulation (6)

  1. Add Binary
  2. Reverse Bits
  3. Number of 1 Bits
  4. Single Number
  5. Single Number II
  6. Bitwise AND of Numbers Range

Lesson · Interactive quiz

20) Math (6)

  1. Palindrome Number
  2. Plus One
  3. Factorial Trailing Zeroes
  4. Sqrt(x)
  5. Pow(x, n)
  6. Max Points on a Line

Lesson · Interactive quiz

21) 1D DP (Including Kadane) (9)

  1. Climbing Stairs
  2. House Robber
  3. House Robber II
  4. Maximum Subarray
  5. Maximum Product Subarray
  6. Word Break
  7. Coin Change
  8. Longest Increasing Subsequence
  9. Decode Ways

Lesson · Interactive quiz

22) 2D DP (7)

  1. Unique Paths
  2. Unique Paths II
  3. Minimum Path Sum
  4. Triangle
  5. Edit Distance
  6. Interleaving String
  7. Maximal Square

Lesson · Interactive quiz

Learning note

After each problem, name the state, justify one discarded alternative, and reconstruct the solution without copying the reference. Quiz items are deliberately appended after each module’s original problem sequence.

Earlier-edition deep links

These anchors preserve links to headings from the original files. They do not reinstate superseded explanations.

Learner experience: how to make this topic stick
The moves to recognize
How to practice without turning it into grind
Debugging instincts to build
A small way to make it memorable

Practice sequence

Use the order below for a guided path, or choose an item to revisit. A pass records a successful attempt; try a fresh example later to check what you can reconstruct.

Join Discord