function pairSum(nums, target) {
let lo = 0, hi = nums.length - 1;
while (lo < hi) {
const s = nums[lo] + nums[hi];
viz.array('nums', nums, { lo, hi }); // the array with two pointers
viz.vars({ s, target }); // variables to watch
viz.note(`sum = ${s}`); // record a frame
if (s === target) return [lo, hi];
if (s < target) lo++; else hi--;
}
return [-1, -1];
}
Coding interviews
A coding-interview trainer: thirty-three patterns with the signals that give them away, animated step-throughs and templates in Python, JavaScript, Java and Go; a clickable pattern map from problem signals to patterns; about 160 original problems with staged hints, reference solutions you can step through line by line, and hidden tests, run in your browser in JavaScript or Python with a scaling check; a visualiser your own code can draw with; a which-pattern quiz; a 45-minute mock interview with a rubric and history; a STAR story bank for the behavioural round; and per-pattern mastery.
Added · updated 30 October 2026
Works with
- Big-O explorer and benchmark Formatting and referencerevise the complexity of what you write here, and see where the scaling check's fit comes from
- Spaced-repetition flashcards Mathematicsthe coding interview patterns and Big-O decks keep the signals and costs in memory between sessions
- Graph algorithms Mathematicsstep through BFS, DFS, Dijkstra and topological sort on graphs you draw
- Concurrency lab Formatting and referencethe concurrency questions that come up beside the algorithm rounds
- System design interviews Interview prepthe design round — a paced framework, estimates and reference architectures you can simulate
How to use it
Most coding-interview problems are one of a small number of patterns in disguise. The fastest way to get better is to learn to recognise the pattern from the problem statement, know its template well enough to write it without thinking, and then practise on problems until the recognising is automatic. This tool is built around that loop. Everything runs in your browser; your code, progress and stories never leave it.
How to use it
Patterns (#learn) has thirty-three patterns: two pointers, sliding window, prefix sums and
hashing, binary search (including searching on the answer), monotonic stack and queue, heaps and
top-k, intervals, linked-list tricks, trees, graphs (BFS, DFS, topological sort, Dijkstra),
union-find, backtracking, dynamic programming (1-D, grid, knapsack, longest increasing
subsequence, string DP), greedy, tries and bit manipulation; then matrix and grid traversal,
cyclic sort, k-way merge, two heaps (the running median), fast and slow pointers on arrays (Floyd’s
cycle detection), the sweep line, segment trees and Fenwick trees, string algorithms (KMP, the
Z-function, rolling hashes and Rabin–Karp, Manacher), shortest paths beyond Dijkstra (0-1 BFS,
Bellman–Ford, Floyd–Warshall), minimum spanning trees (Kruskal, Prim), bitmask DP, digit and
state-machine DP, designing a data structure (LRU and LFU caches and others), randomised
algorithms (reservoir sampling, shuffling, quickselect), maths and number theory (gcd, the sieve,
modular powers, combinations), geometry basics (orientation, areas, convex hulls) and concurrency
puzzles, which go with the concurrency lab. For each you get:
-
Recognise it — the signals in a problem statement that point to the pattern;
-
Step through it — the algorithm running on a small input, one move at a time, with the pointers, windows, stacks, heaps, tables or graphs drawn, a note on every step and, for most demos, the code beside it with the current line lit. Use the buttons, the scrubber or the arrow keys, or Play;
-
Template — a skeleton to adapt, in Python, JavaScript, Java and Go, with a copy button;
-
Complexity and Pitfalls — the usual costs, and the mistakes that cost people the interview;
-
Practise it — the problems that use the pattern.
The dot on each pattern’s button shows your mastery of it. The Java and Go templates show the
technique, not whole programs: they leave out imports and wrappers, and the Go ones use the
built-in min and max of Go 1.21 and later.
Pattern map (#map) goes the other way, from a problem to its pattern. Answer a question or
two about what the problem gives you and asks for — a contiguous piece of an array, a sorted
input, a grid, a graph, intervals, the best over a series of choices… — and it narrows down to the
patterns that fit, with the signal that decides it, the pattern’s main signals, and links to the
pattern and its problems. Below the questions, the whole map is drawn as a tree; click any
pattern in it to open it.
Practice (#practice) has about 160 problems, each written for this tool, tagged by pattern
and by difficulty (easy, medium, hard), with at least three for every pattern. Pick one from the list, read the statement and examples,
and write a solution in JavaScript or Python in the editor; your code is saved as you type, per
problem and language.
-
Run examples (Ctrl/⌘+Enter) runs the visible tests; Submit (Ctrl/⌘+Shift+Enter) runs the hidden ones too. Each test shows pass or fail, what you returned, how long it took, and anything your code printed. Hidden tests stay hidden, except that the first one you fail is shown.
-
Show a hint gives up to three hints, from a nudge to nearly the answer. Show the solution shows the reference solution in both languages, why it is correct, and its complexity.
-
Step through the solution runs the reference solution on a small example (or any of the visible examples) and plays it back line by line: the current line is lit in the code, the variables are listed with the ones that just changed marked, and the data is drawn — arrays and strings with their pointers and windows, linked lists, trees, heaps (as a tree and as an array), tries, graphs with visited and waiting nodes and distances, grids, DP tables filling cell by cell with arrows from the cells each one reads, stacks, queues, hash maps, union-find forests, intervals on a number line, segment and Fenwick trees, bits, points, and for recursive code the recursion tree with each call’s return value and the call stack. It works for every problem, in JavaScript at once or in Python (which loads Pyodide first). Like the solution, it counts as looking at the answer.
-
Visualise steps through your code on one input in the same way. With no
vizcalls in it, your code is traced line by line and its variables are drawn automatically. Or draw exactly what you want with thevizAPI, below. -
Scaling check times your passing solution on inputs of growing size and fits the timings to a complexity class, with the same method as the Big-O tool's benchmark: it says whether your code scales like the reference (O(n) against O(n²), say). Timings are noisy on small inputs; treat it as a hint, and run it again if the verdict surprises you.
Linked-list problems pass and return lists written as arrays ([1, 2, 3] is 1 → 2 → 3), and
tree problems use level order with null for a missing child ([3, 9, 20, null, null, 15, 7]);
ListNode and TreeNode are defined for you in both languages.
Visualising your own code
Your solution can call viz while it runs, and Visualise plays back what it drew. Each call
updates a named picture; viz.note(text) records a frame with that note, and calling the same
picture again before a note records one too, so drawing an array once per loop gives a frame per
pass. The name can be left out (viz.tree(root)). During Run examples, Submit and the scaling
check the calls do nothing, so you can leave them in.
| Call | Draws |
|---|---|
|
an array with named pointers and a shaded window |
|
a string, a cell per character |
|
a linked list (pointers may be nodes); a cycle is shown |
|
a binary tree, or a level-order array |
|
an array as a binary heap, and as the array |
|
a grid |
|
a DP table, with arrows from the cells the current one reads |
|
a graph, from an adjacency list or an edge list |
|
collections and hash maps |
|
a union-find forest |
|
intervals on a number line, with a sweep line at |
|
range-query trees, bits, points, tries |
|
variables to show |
|
record a frame |
Marks are cur, hit, done, frontier, dim, bad and new. For example, in JavaScript:
Python has the same calls in a viz module, with pointers as keywords:
import viz
def pair_sum(nums, target):
lo, hi = 0, len(nums) - 1
while lo < hi:
s = nums[lo] + nums[hi]
viz.array("nums", nums, lo=lo, hi=hi)
viz.vars(s=s, target=target)
viz.note(f"sum = {s}")
...
?example=visualise opens a problem
with this example in the editor and plays it.
Which pattern? (#quiz) shows a problem statement and asks which pattern solves it, then
explains the signal. It mixes short statements written for the quiz with the practice problems,
and it can be limited to one pattern. Keys 1–4 answer.
Mock interview (#mock) picks a random problem (unsolved ones first) at the difficulty you
choose and runs a 45-minute clock in five phases: clarify (5 minutes), approach (10), code (20),
test (5) and complexity (5), with a tip for each phase. Hints are there, the solution is not.
Pause stops the clock, and a mock in progress survives a reload. Finish and score opens a
rubric — understanding, problem solving, code, testing, and communication and complexity, each
scored 1 to 4 with a description of each level — and saves the attempt, with your notes and the
tests passed, to a history you can look back on.
Behavioural (#stories) is a bank of your own STAR stories (situation, task, action,
result), tagged with the competency themes they can answer: ownership, disagreement, failure,
ambiguity, impact, influence, leadership, mentoring, pressure, prioritisation, customer focus,
collaboration, learning, judgement and motivation. Each story is checked as you write it: missing
parts, an action section that is too short or says "we" more than "I", a result without a number,
and roughly how long it takes to say. The coverage grid shows which themes have no story yet.
Practise answering shuffles a question (all themes, or the ones you pick), lists the stories
tagged for its theme, and runs a countdown of one to three minutes.
Progress (#progress) shows mastery per pattern from 0 to 100: up to 70 for solving its
problems (weighted by difficulty; each hint used takes a little off, and solving after revealing
the solution counts half), up to 20 for the which-pattern quiz (your accuracy over the last
twenty answers, in full from five answers), and 10 for stepping through the pattern’s demo to the
end. It suggests problems to try next from your weakest patterns, and Export JSON saves
everything — progress, drafts, mock history and stories — to a file that Import JSON reads
back.
Running your code
JavaScript runs in a Web Worker, so an infinite loop cannot freeze the page: a run that takes
longer than 6 seconds is stopped. Python is CPython 3.12 compiled to WebAssembly by
Pyodide, the same release the Python
notebook uses. It is loaded from cdn.jsdelivr.net the first time you run Python (about 10 MB,
then cached by the browser), runs in its own worker, and is restarted if a run takes longer than
12 seconds. That download is the only network request this tool makes. The scaling check loads
/tools/bigo.js from this site for its curve fitting; for Python it uses inputs an eighth of the
JavaScript sizes, because CPython in WebAssembly is much slower than JavaScript.
Limits
-
Only JavaScript and Python run here. The templates are also in Java and Go, to read and copy.
-
Problems are functions with arguments and a return value. Design problems (an LRU cache, say) take a list of operations and return the list of their outputs; your class lives inside the solution. Problems that change their input in place are checked by looking at the input afterwards. Randomised problems are given their "random" numbers as an argument, or have an answer that does not depend on them.
-
The line-by-line step-through records up to 800 steps (and Visualise up to 600 frames), on one input; the run still finishes after that. In JavaScript it follows named functions and methods, not anonymous callbacks such as a sort comparator, and the body of an
ifor loop written without braces runs as one step; it needs balanced brackets and semicolons where JavaScript would otherwise guess them. Pointers are guessed from names (i,j,lo,hi,left,right,slow,fast…) and drawn under the first array or string argument; draw anything else withviz. A quickselect with random pivots steps differently each time. -
Answers that can come in any order (groups, subsets) are compared ignoring order; decimals are compared to six significant figures.
-
The scaling check needs at least three sizes to finish, and takes up to about a minute in Python. It measures this browser on this machine, so JIT warm-up and garbage collection can blur close classes such as O(n) and O(n log n).
-
Mastery, drafts, history and stories are kept in this browser’s local storage. Clearing site data deletes them; export a copy first.
Linking to an example
Share link copies a URL that opens the tool on the pattern or problem you are looking at. Links
can also be written by hand: the part after # picks the tab (learn, map, practice,
quiz, mock, stories, progress). For example
?problem=longest-unique-run&lang=py#practice
opens a sliding-window problem in Python.
| Parameter | Meaning | Example |
|---|---|---|
|
a pattern: |
|
|
a practice problem, by its id; opens the practice tab |
|
|
the language for the editor: |
|
|
filter practice problems by difficulty: |
|
|
one of the presets below; other parameters override it |
|
| Example | Opens |
|---|---|
|
the two-pointers pattern and its step-through (open) |
|
the sliding window, fixed and variable |
|
binary search, including searching on the answer |
|
dynamic programming: 1-D, grid, knapsack, LIS and string DP |
|
graph traversal, topological sort and Dijkstra |
|
an easy first problem in JavaScript (open) |
|
a sliding-window problem in Python |
|
the hard dynamic-programming problems |
|
the which-pattern quiz |
|
a mock interview |
|
the behavioural story bank |
|
the pattern map (open) |
|
string algorithms: KMP, the Z-function and rolling hashes |
|
segment trees and Fenwick trees |
|
0-1 BFS, Bellman–Ford and Floyd–Warshall |
|
design an LRU cache, in JavaScript |
|
a problem with |
Feedback is a gift. Something to improve, a feature to add, or a bug? Tell me.
Runs entirely in your browser — network requests go only to the services named on this page.