Chapter 13

Problem sets

Curated LeetCode-style problems grouped by pattern with worked solutions.

Problem sets

A curated list is only useful if each problem teaches something the previous ones did not. This file maps the canonical lists onto the patterns in Algorithm patterns, Graphs and trees and Dynamic programming, so you practise a pattern rather than accumulating solved problems.

It also starts with what interviews actually look like now, because “grind 500 problems” is 2019 advice and the format has moved.

Table of contents


1. What technical interviews look like in 2026

Worth reading before you pick a list, because it changes what to optimize for. The consistent themes across current write-ups (see Sources — and note that much of this is practitioner observation rather than published data):

  • Algorithm rounds still exist at large companies, but grinding alone is no longer sufficient. The same patterns are tested; the questioning around them got harder.
  • Live coding has been made AI-resistant in three ways: broken code you must debug and fix, real-time “why this data structure and not that one” probing, and collaborative framing where the interviewer changes the requirements mid-problem to see how you adapt.
  • A new “AI-assisted” round exists at some companies: you are given the tools and evaluated on judgement — what you delegate, what you verify, whether you can defend the generated design. Take-home exercises now often expect AI use and ask you to justify the choices.
  • System design moved earlier. What used to be a senior-only round now appears at mid-level and occasionally new-grad, because it is harder to fake.
  • Behavioural rounds got heavier and more structured — specific stories, measurable outcomes, follow-up probes.
  • Onsites came back at some companies, partly because remote rounds were being gamed.

What this means for your prep, given that the thing you are rusty on is fundamentals:

Old habitBetter use of the same hour
Solve a new problem, read the answer, move onSolve one problem, then explain the invariant out loud, then do one variant from memory
Optimize for problem countOptimize for pattern coverage plus the ability to derive complexity unprompted
Memorize solutionsMemorize templates (sliding window, binary search on the answer, DFS with memo) and re-derive the rest
Skip the “why”Practise the sentence “I chose a heap here because I only need the extremum, not the order” — that sentence is the signal now
Only write codePractise reading broken code and finding the bug. This is an actual round now

The corollary that matters for someone who has been vibecoding: the parts an AI does well for you (typing out a known algorithm) are the parts that are now least valued in the room, and the parts it cannot do for you (choosing, justifying, adapting, debugging live) are the parts being tested harder. That is good news — it means fluency in fundamentals is worth more, not less.


2. Which list, and how to use it

ListCountDifficulty splitOriginBest for
Blind 757514 E / 49 M / 12 HAmazon engineer, 2020, posted anonymously on BlindUnder three weeks. Hits every major pattern once — the fastest route to pattern recognition
LeetCode 75756 E / 53 M / 16 HLeetCode’s own 2022 study planSame role as Blind 75, slightly more medium-heavy, integrated tooling
NeetCode 15015021 E / 90 M / 39 Hex-Google engineer; superset of Blind 75Three to six weeks. 3-15 problems per pattern instead of one, so the pattern actually sticks
NeetCode 250250expanded furtherMore than six weeks, or targeting a company known for hard rounds
Grind 75configurableex-Meta engineer; generates a schedule from your available hoursWhen you want the schedule decided for you

All of them organize around the same ~14 patterns, which are the ones in Algorithm patterns §1. The lists differ in depth per pattern, not in coverage.

The honest recommendation for your situation (experienced, rusty on fundamentals rather than new to them): do not start with a list at all. Start with the implement-from-scratch drills in section 6 — you will recover far more per hour by rebuilding a heap, a trie and a DSU than by solving three medium problems. Then work section 3 for coverage, and only go to NeetCode 150/250 for depth on the patterns that still feel slow.

The rule that makes any list work: solve, then re-solve from a blank file the next day. Pattern recognition comes from retrieval, not from reading solutions. That is what the spaced-repetition schedule in the study plan is for.


3. The core 80, by pattern

One or two problems per pattern, chosen so that each teaches a distinct technique. This is roughly Blind 75 reorganized so the pattern is the unit, plus a few additions where Blind 75 has a gap. Each row names the transferable idea, which is the thing to be able to state after solving it.

Arrays and hashing

ProblemThe transferable idea
Two Sumcomplement lookup in a hash map; O(n) instead of O(n^2)
Contains Duplicateset membership as the default de-duplication move
Valid AnagramCounter equality / frequency map
Group Anagramsa canonical key (sorted string, or a 26-tuple) as the grouping key
Top K Frequent Elementscount then heap of size k, O(n log k)
Product of Except Selfprefix from the left, suffix from the right, no division
Encode and Decode Stringslength-prefixed encoding is delimiter-safe
Longest Consecutive Sequenceset membership turns an O(n log n) sort into O(n)

Two pointers

ProblemThe transferable idea
Valid Palindromeconverging pointers with skip conditions
Two Sum II (sorted input)the “one move is always safe” argument
3Sumfix one, two-pointer the rest; dedup at two places
Container With Most Watermove the shorter side — the exchange argument
Trapping Rain Watertwo pointers carrying running maxima, O(1) space
Remove Duplicates from Sorted Arrayread cursor + write cursor for in-place compaction
Sort Colorsthree-way partition (Dutch national flag)

Sliding window

ProblemThe transferable idea
Best Time to Buy and Sell Stockrunning minimum; the degenerate one-state DP
Longest Substring Without Repeating Charactersjump start past the last occurrence, do not step
Longest Repeating Character Replacementwindow - maxfreq <= k, and why stale maxfreq is safe
Permutation in Stringfixed-size window with a frequency match
Minimum Window Substringshrink-while-valid for a minimum; surplus counts go negative
Sliding Window Maximummonotonic deque; each index pushed and popped once
Minimum Size Subarray Sumshrink-while-valid, and why negatives break it

Stack

ProblemThe transferable idea
Valid Parenthesesstack as a matcher; map closing to opening
Min Stacka parallel stack of running minima gives O(1) min
Evaluate Reverse Polish Notationstack machine evaluation
Generate Parenthesesbacktracking with a validity invariant instead of generate-and-filter
Daily Temperaturesmonotonic stack; the pop is when you learn the answer
Car Fleetsort by position, then a monotonic stack of arrival times
Largest Rectangle in Histogrammonotonic stack + sentinel to flush it
ProblemThe transferable idea
Binary Searchpick one template and always write it
Search a 2D Matrixtreat the matrix as a flat sorted array
Koko Eating Bananasbinary search the answer with a monotone feasibility predicate
Find Minimum in Rotated Sorted Arraycompare to a[hi], not a[lo]
Search in Rotated Sorted Arrayone half is always sorted; decide which
Time Based Key-Value Storebisect over timestamps
Median of Two Sorted Arrayssearch the partition point, with +/-inf sentinels

Linked list

ProblemThe transferable idea
Reverse Linked Listthree-pointer iterative reversal
Merge Two Sorted Listsdummy head removes the first-node special case
Reorder Listfind middle + reverse second half + interleave
Remove Nth Node From Endopen a gap of n, then walk both
Copy List With Random Pointera map from old node to new node (or the O(1)-space interleave trick)
Add Two Numberscarry propagation with a dummy head
Linked List CycleFloyd’s tortoise and hare
Find the Duplicate NumberFloyd on the index -> value functional graph
LRU Cachehash map + doubly linked list, O(1) both operations
Merge K Sorted Listsheap of size k, O(n log k)

Trees

ProblemThe transferable idea
Invert Binary Treethe shape of every simple tree recursion
Maximum Depth of Binary Treeboth the recursive and the level-order form
Diameter of Binary Treereturn the height, accumulate the answer separately
Balanced Binary Treea -1 sentinel turns O(n^2) into O(n)
Same Tree / Subtree of Another Treestructural comparison; hashing subtrees for the follow-up
Lowest Common Ancestor of a BSTwalk down while both targets are on the same side
Binary Tree Level Order Traversalsnapshot the level size before appending children
Binary Tree Right Side Viewlast node of each BFS level
Count Good Nodes in Binary Treepass an accumulator down (pre-order)
Validate Binary Search Treein-order monotonicity, or (lo, hi) bounds
Kth Smallest Element in a BSTin-order with a counter, or subtree sizes for O(h)
Construct Binary Tree from Preorder and Inorderwhy those two determine the tree
Binary Tree Maximum Path Sumclamp negative branches to 0; the path can bend
Serialize and Deserialize Binary Treepre-order with explicit null markers

Tries

ProblemThe transferable idea
Implement Triethe structure itself
Design Add and Search Words (wildcards)DFS over children when the pattern char is .
Word Search IIwalk the board and the trie in lockstep; prune on invalid prefix

Heap / priority queue

ProblemThe transferable idea
Kth Largest Element in a Streammin-heap of size k
Last Stone Weightmax-heap via negation in Python
K Closest Points to Originheap vs quickselect trade-off
Kth Largest Element in an Arrayquickselect O(n) expected vs heap O(n log k)
Task Schedulergreedy with a closed-form answer, or a heap simulation
Find Median from Data Streamtwo heaps with a balance invariant

Backtracking

ProblemThe transferable idea
Subsetsinclude/exclude, and remembering to copy
Combination Sumreuse allowed -> recurse on i, not i+1
Permutationsswap into position, undo after
Subsets II / Combination Sum IIsort, then skip duplicate siblings (i > start)
Word Searchin-place visited marking
Palindrome Partitioningbacktracking with a precomputed palindrome table
N-Queenspruning with three sets (columns and the two diagonal families)

Graphs

ProblemThe transferable idea
Number of Islandsgrid DFS/BFS with in-place marking
Clone Grapha visited map from original to copy
Pacific Atlantic Water Flowreverse the direction and BFS from the borders
Surrounded Regionsmark from the boundary, then flip the rest
Rotting Orangesmulti-source BFS by levels
Course Schedulecycle detection = topological sort feasibility
Course Schedule IIthe order itself (Kahn, or reverse DFS post-order)
Redundant Connectionunion-find; the first edge that joins two connected nodes
Number of Connected ComponentsDSU or repeated traversal
Word LadderBFS with lazily-built wildcard adjacency
Network Delay TimeDijkstra
Cheapest Flights Within K StopsBellman-Ford bounded to k+1 relaxation rounds
Min Cost to Connect All PointsMST (Prim on a dense graph)
Alien Dictionarytopological sort on a derived precedence graph
Reconstruct ItineraryHierholzer’s Eulerian path

1D dynamic programming

ProblemThe transferable idea
Climbing Stairsthe base case of the whole topic
Min Cost Climbing Stairsthe same recurrence with a cost
House Robber / House Robber IItwo running states; circular via two linear runs
Longest Palindromic Substringexpand around 2n-1 centers
Palindromic Substringsthe same expansion, counting
Decode Wayslook back one and two characters
Coin Changeunbounded knapsack, minimize
Maximum Product Subarraycarry both the max and the min
Word Breakdp over prefixes, membership in a set
Longest Increasing SubsequenceO(n^2), then the O(n log n) patience version
Partition Equal Subset Sumsubset-sum reachability (bitset in Python)

2D dynamic programming

ProblemThe transferable idea
Unique Pathsthe simplest grid DP; rolling row
Longest Common Subsequencethe two-sequence template
Best Time to Buy and Sell Stock with Cooldownstate machine DP
Coin Change IIcombinations vs permutations, decided by loop order
Target Sumreduce a +/- assignment to subset-sum counting
Interleaving Stringtwo pointers as a 2D DP
Longest Increasing Path in a Matrixmemoized DFS when the order is implicit
Distinct Subsequences1D with a backward loop
Edit Distancethree choices: replace, insert, delete
Burst Balloonsinterval DP; think about the last operation
Regular Expression MatchingDP with * handling; the classic hard one

Greedy

ProblemThe transferable idea
Maximum SubarrayKadane
Jump Game / Jump Game IIfurthest reach; BFS-by-levels as a scan
Gas Stationtotal feasibility plus a local reset
Hand of Straightsgreedy from the smallest remaining card
Merge Triplets to Form Targetfilter then union
Partition Labelsextend to the last occurrence
Valid Parenthesis Stringtrack a min/max open range

Intervals

ProblemThe transferable idea
Insert Intervalthree phases: before, merge, after
Merge Intervalssort by start, extend with max
Non-overlapping Intervalssort by end — the exchange argument
Meeting Rooms / Meeting Rooms IImax concurrency via heap or sweep line
Minimum Interval to Include Each Queryoffline: sort queries, heap by length

Bit manipulation and math

ProblemThe transferable idea
Single NumberXOR cancels pairs
Number of 1 Bitsn & (n-1) clears the lowest set bit
Counting Bitsdp[i] = dp[i>>1] + (i&1)
Reverse Bitsshift-and-accumulate
Missing NumberGauss sum or XOR
Sum of Two IntegersXOR is sum-without-carry, (a&b)<<1 is the carry
Rotate Imagereverse rows then transpose
Spiral Matrixfour boundaries, or peel-and-rotate
Set Matrix Zeroesuse row 0 / column 0 as markers for O(1) space
Pow(x, n)fast exponentiation by squaring
Happy NumberFloyd’s cycle detection on a functional graph

4. The second 70: pattern depth

Once every row in section 3 is comfortable, the value is in variations — the same pattern where a small change in the problem forces a change in the technique. This is what NeetCode 150/250 adds over Blind 75, and it is where pattern recognition becomes automatic.

PatternVariations worth doing, in order
Sliding windowLongest Substring with At Most K Distinct; Fruit Into Baskets; Subarrays with K Different Integers (the “exactly K = at most K minus at most K-1” trick); Count Number of Nice Subarrays; Max Consecutive Ones III; Sliding Window Median (needs a sorted structure)
Two pointers4Sum; 3Sum Closest; Boats to Save People; Squares of a Sorted Array; Longest Mountain in Array
Binary search on the answerSplit Array Largest Sum; Capacity To Ship Packages; Minimum Number of Days to Make m Bouquets; Magnetic Force Between Two Balls; Find K-th Smallest Pair Distance; Kth Smallest Element in a Sorted Matrix
Monotonic stackSum of Subarray Minimums (contribution counting); Maximal Rectangle; Remove K Digits; 132 Pattern; Next Greater Element II (circular); Online Stock Span
Prefix sumsSubarray Sum Equals K; Subarray Sums Divisible by K; Contiguous Array; Range Sum Query 2D; Corporate Flight Bookings (difference array); Car Pooling
HeapReorganize String; Minimum Cost to Hire K Workers; IPO; Sliding Window Median; Smallest Range Covering K Lists; Design Twitter
Union-findAccounts Merge; Number of Provinces; Satisfiability of Equality Equations; Most Stones Removed; Smallest String With Swaps; Number of Islands II (online)
Topological sortMinimum Height Trees; Sequence Reconstruction; Parallel Courses; Sort Items by Groups Respecting Dependencies
Shortest pathPath With Minimum Effort (binary search + BFS, or Dijkstra on max-edge); Swim in Rising Water; Path with Maximum Probability; Minimum Obstacle Removal (0-1 BFS); Cheapest Flights (Bellman-Ford)
Tree DPHouse Robber III; Distribute Coins in Binary Tree; Binary Tree Cameras; Longest Univalue Path; Sum of Distances in Tree (rerooting)
Interval DPMinimum Cost to Merge Stones; Strange Printer; Remove Boxes; Minimum Score Triangulation
Bitmask DPPartition to K Equal Sum Subsets; Shortest Path Visiting All Nodes; Number of Ways to Wear Different Hats; Minimum Incompatibility; Maximum Students Taking Exam
Digit DPCount Numbers with Unique Digits; Numbers At Most N Given Digit Set; Non-negative Integers without Consecutive Ones; Count of Integers
DesignLRU Cache; LFU Cache; Design Twitter; Insert Delete GetRandom O(1); Design Hit Counter; Snapshot Array; Time Based Key-Value Store; Design Search Autocomplete
MatrixGame of Life (in-place with bit encoding); Diagonal Traverse; Toeplitz Matrix; Rotate Image; Word Search II
StringsRepeated Substring Pattern (KMP failure function); Shortest Palindrome (KMP on s + rev(s)); Longest Duplicate Substring (binary search + rolling hash); Minimum Window Subsequence

The “exactly K = atMost(K) - atMost(K-1)” reduction in the sliding-window row is worth calling out — it converts a problem the window cannot solve directly into two problems it can, and it generalizes to a surprising number of counting questions.


5. Language-specific practice

Problems whose point is a language feature rather than an algorithm. These are the ones that make the difference between “knows algorithms” and “writes idiomatic TypeScript / Python”.

TypeScript and JavaScript

DrillWhat it testsReference
Implement Promise from scratch, passing a small test suitethenable adoption, single settlement, microtask orderingJS core §6.5
Implement Promise.all, allSettled, any, racecombinator semantics and error behaviourJS core §6.4
Implement bind, call, applythis, the new case, prototype chainJS core §12.1
Implement map, filter, reduce on Array.prototypeholes (i in this) and the empty-with-no-initial TypeErrorsame
Deep clone with cycles; deep equalWeakMap/Map memo, Reflect.ownKeys, descriptorssame
debounce (leading/trailing) and throttleclosures, timers, this forwardingJS core §4.5
Bounded-concurrency pMap with retriespromise pooling, order preservation, error policyJS core §6.8
Typed EventEmitter from an event mapmapped types, conditional rest parametersTS types §11.2
DeepPartial, UnionToIntersection, Paths<T>conditional/mapped/template-literal typesTS types §10
Predict-the-output event loop puzzlesmicrotasks, nextTick, setImmediate orderingJS core §6.3
Explain why one loop is 4x slower than anotherinline caches, packed vs holey arraysJS core §8

Python

DrillWhat it testsReference
Write a decorator with arguments, then stack twothree-level closures, functools.wraps, orderPatterns §3.3
Write a context manager both ways__enter__/__exit__, suppression, @contextmanagerPatterns §3.4
Write a descriptor that validates, and a mini propertythe attribute lookup orderPython core §3.2
Predict the MRO of a diamond, and what super() resolves toC3 linearizationPython core §3.3
Demonstrate the GIL with threads vs processeswhat the GIL protectsPython core §6.2
Make a generator pipeline that never materializes a listlaziness, yield fromPython core §4.2
Build a priority queue with tie-breaking on unorderable payloadsthe (priority, counter, item) idiomPy data structures §7
Use bisect to answer floor / ceil / rank / countleft vs right semanticsPy data structures §8
Explain when s += x in a loop is linear and when it is quadraticCPython’s in-place resize optimizationComplexity §9.3
Convert a recursive solution to iterative for n = 1e5the 1000-frame recursion limitComplexity §4.1
Write a match-based state machine over frozen dataclassesstructural pattern matching, immutabilityPatterns §3.14

6. Implement-from-scratch drills

Do these before the problem lists. Each one is 15-40 minutes, and each rebuilds a specific piece of machinery you will otherwise fumble under pressure. Do them in both languages at least once; do the starred ones in both languages every review cycle.

#DrillTarget timeReference
1Dynamic array with growth, and state the amortized proof *15 minTS §7 / Py §12
2Singly linked list + reverse, cycle detect, merge, middle *25 minTS §8 / Py §13
3Ring-buffer queue and a two-stack queue20 minTS §10 / Py §14
4Hash table: chaining, then open addressing with tombstones40 minTS §12 / Py §15
5Binary min-heap with sift up/down and O(n) heapify *25 minTS §13 / Py §16
6Median finder with two heaps15 minsame
7BST insert/delete (all 3 cases) + iterative in-order *30 minTS §14 / Py §17
8AVL insert with all four rotation cases40 minTS §15 / Py §18
9Trie: insert / search / startsWith / autocomplete *25 minTS §16 / Py §19
10Union-Find with path compression and union by size *15 minTS §17 / Py §20
11LRU cache, both the map trick and the linked-list version *25 minTS §19 / Py §22
12Segment tree (sum + min) and a Fenwick tree40 minTS §20 / Py §23
13Merge sort, quicksort with random pivot, heapsort *35 minSorting §3-5
14Binary search: exact, lower_bound, upper_bound, first-true *20 minSorting §10
15Quickselect15 minSorting §9
16BFS + DFS (iterative) + topological sort both ways *30 minGraphs §2, §4
17Dijkstra with lazy deletion, then with decrease-key30 minGraphs §6
18Kruskal and Prim25 minGraphs §7
19Bloom filter with the sizing formula20 minTS §22 / Py §25
20Promise from scratch (JS) / a decorator with arguments (Py) *30 minJS §6.5 / Py patterns §3.3

Every one of these has a tested reference implementation in this guide, so you can diff your version against something that provably runs.


7. Debug-and-fix and code-review drills

A real round now. Practise by writing the bug yourself and fixing it a day later, or by reviewing code that contains one of these classic defects. Each of these is a bug from the measured sections of this guide, so you know the failure mode is real.

SnippetThe bugWhy it is subtle
BFS with queue.pop(0) / arr.shift()O(n) dequeue makes the whole traversal O(V^2)correct output, 145x slower at n=32k
s += chunk in a Python loop where another name holds squadratic instead of linearthe same code is linear when the refcount is 1
[[0]*n]*m gridevery row is the same listonly shows up when you mutate
arr.sort() on numbers in JSlexicographic ordering[1,10,9] looks almost sorted
if x: where 0 is a valid valuefalsy-value bugworks until the data contains 0 or ''
def f(x, acc=[])shared mutable defaultworks on the first call
Marking visited on dequeue in BFSqueue grows to O(E), duplicates processedstill correct, just slow
dp[c-w] with a forward capacity loop in 0/1 knapsackitems reusedpasses the small example
Missing seen[0] = 1 in prefix-sum countingmisses subarrays starting at index 0off by exactly the easy cases
i > 0 instead of i > start in dedup backtrackingskips legitimate repeatswrong count only for some inputs
Validating a BST against immediate children only[10,5,15,null,null,6,20] passesthe standard example does not catch it
Dijkstra with a negative edgesilently wrong answerno error, no crash
Floyd-Warshall with k in an inner loopwrong for some graphsright for many test cases
delete arr[i] on a hot JS arraypermanent deoptimization40% slower forever, invisible in the output
Bloom filter index computed with signed 32-bit overflowfalse negativesbreaks the one guarantee the structure makes
Object.assign where descriptors mattergetters invoked, readonly lostlooks like a copy
except: bareswallows KeyboardInterrupt and CancelledErrortests pass, production hangs
@lru_cache on a methodleaks every self forevermemory grows slowly
for await over an array of promisesfully sequentialcorrect results, N times slower
Mutating a list while iterating it forwardskipped elementssilently drops data

The exercise is not just “find the bug” — it is “say what the failure mode is, how you would have caught it, and what test you would add”. That is what the round is actually scoring.


8. How to practise one problem properly

flowchart TD
    A["1. Restate problem +<br/>ask clarifying questions"] --> B["2. State brute force<br/>and its complexity"]
    B --> C["3. Name the pattern<br/>and why"]
    C --> D["4. State the invariant<br/>before coding"]
    D --> E["5. Write it<br/>(narrate only the interesting lines)"]
    E --> F["6. Trace a small example,<br/>including an edge case"]
    F --> G["7. State time/space<br/>and the bottleneck"]
    G --> H["8. Close the file"]
    H -.->|"next day, from a<br/>blank file"| A

The difference between an hour that builds fluency and an hour that does not:

  1. Restate the problem and ask two clarifying questions before writing anything. Input size? Sorted? Duplicates? Negative values? In-place allowed? This is now explicitly scored — “more emphasis on clarifying questions before coding” is one of the documented 2026 shifts.
  2. Say the brute force and its complexity out loud, even when it is obviously too slow. It establishes a baseline and often reveals the redundancy the real solution removes.
  3. Name the pattern and why. “Contiguous subarray plus a monotone constraint, so sliding window.”
  4. State the invariant before coding. “The window [left, right] always contains at most k distinct characters.” Bugs come from not having one.
  5. Write it. Talk through the interesting lines only; narrating a for loop wastes the room’s time.
  6. Trace one small example by hand, including an edge case (empty, single element, all equal).
  7. State time and space, and where the bottleneck is. Volunteer the follow-up: “the n log n is only the sort; if the input arrived sorted this is linear.”
  8. Then, away from the interview: close the file and rewrite the solution from scratch the next day. Retrieval is what builds the reflex; re-reading a solution builds only recognition.

Two habits worth adopting specifically because of how interviews changed:

  • Defend a data-structure choice unprompted. “I’m using a Map here rather than an object because the keys are dynamic, and a plain object used as a dictionary goes into slow mode anyway.” That sentence is the differentiator now.
  • Practise being interrupted. Have a friend or a model change the requirements halfway (“now the input is streaming”, “now the values can be negative”, “now it has to be O(1) space”) and adapt out loud. The collaborative-framing round is exactly this.

Track your progress by pattern confidence, not problem count. A simple table with the 14 patterns and a 1-5 confidence score, updated weekly, tells you what to practise next far better than a streak does. The study plan has a version of that table plus the review schedule.


9. Sources

Facts about list composition and the 2026 format shift come from:


Next: Cheat sheets for the quick reference, or Study plan and flashcards to schedule the work.