1. Sort by x
Sorting by x once lets each recursion split at the median x in order.
const byX = [...points].sort((a, b) => a.x - b.x)Typorithm · hard
Step 1 of 8 · intro card
Divide & Conquer
Sort by x, recurse on each half, take the smaller distance d, then check only points within a 2d-wide vertical strip, sorted by y.
Sort points by x once, then split at the median x and recurse on each half.
Let d be the smaller of the two halves' closest distances; any closer pair must straddle the midline within a strip of width 2d.
Sort the strip by y and compare each point only to the next few whose y-distance is below d — a constant number per point, keeping the combine step linear.
d = min of the two halves first.
Strip width is 2d around the midline.
Each strip point checks only a few y-neighbors.
function closestPair(points) {
const byX = [...points].sort((a, b) => a.x - b.x);
function dist(a, b) {
return Math.hypot(a.x - b.x, a.y - b.y);
}
function solve(lo, hi) {
if (hi - lo <= 3) {
let best = Infinity;
for (let i = lo; i < hi; i += 1) {
for (let j = i + 1; j < hi; j += 1) {
best = Math.min(best, dist(byX[i], byX[j]));
}
}
return best;
}
const mid = Math.floor((lo + hi) / 2);
const midX = byX[mid].x;
let d = Math.min(solve(lo, mid), solve(mid, hi));
const strip = [];
for (let i = lo; i < hi; i += 1) {
if (Math.abs(byX[i].x - midX) < d) strip.push(byX[i]);
}
strip.sort((a, b) => a.y - b.y);
for (let i = 0; i < strip.length; i += 1) {
for (let j = i + 1; j < strip.length && strip[j].y - strip[i].y < d; j += 1) {
d = Math.min(d, dist(strip[i], strip[j]));
}
}
return d;
}
return solve(0, byX.length);
}Connect each part of the code to the concept before you type.
Sorting by x once lets each recursion split at the median x in order.
const byX = [...points].sort((a, b) => a.x - b.x)With three or fewer points, brute-force every pair directly.
if (hi - lo <= 3)Recurse into each half; d is the smaller of the two halves' best distances.
let d = Math.min(solve(lo, mid), solve(mid, hi))Only points within distance d of the midline can beat d across halves.
if (Math.abs(byX[i].x - midX) < d) strip.push(byX[i])Sorting the strip by y bounds each point to a few following neighbors.
strip.sort((a, b) => a.y - b.y)Stop once the y-gap reaches d; only a constant number of points qualify.
strip[j].y - strip[i].y < dRead the concept map and follow the code breakdown.
Type the implementation, repair mistakes and work through every recall exercise.
Use the final check without hints; revisit weak concepts in short practice sessions.
Algorithm lab · interactive
InputPoints (1,1), (2,6), (4,4), (5,5), (7,2), (8,8)
Follow temporary values, local state and supporting structures at this step.
No temporary values have been saved in this frame yet.
Around this step
Small, reproducible examples · ← → step · Space play/pause · Home/End first/last state