workshop private

← all creations

Weave

viz · created 2026-09-28

The LC 143 Reorder List drawn as the three moves it is made of — slow/fast to the middle, the back half cut off and reversed one pointer write at a time, then the two halves woven together — with nodes fixed where they sit in memory, every backward pointer arcing over the top, and a walk from the head underneath that says whether the list is whole right now. The cut and the middle are each switchable to their bug, so a forgotten cut is a cycle you watch close.

algorithmsinterview-prepcanvas

Reorder List (LC 143): a singly linked list L0 → L1 → … → Ln−1, reordered in place to L0 → Ln−1 → L1 → Ln−2 → L2 → … by rewiring nodes, never by moving values. The brief’s sentence is the whole problem — you need the back half in reverse while still walking the front half forward, and only one of those directions is free in a singly linked list — so the answer is three moves in a row, and the piece draws them as pointer writes and nothing else. The boxes never move; that is where the nodes are in memory. Each next is an arrow: a straight line to the neighbour, an arc under the row for a forward skip, an arc over the row the moment a pointer points backward, which is how you watch the reversed half accumulate. The pointer that changed on this frame is white. Named variables (slow, fast, prev, cur, a, b, and the saved nxt / an / bn) sit under the box they hold.

Under the row, walk from head is the list as a traversal would see it at this exact instant — the nodes reachable from the head, in order, ending in ∅ — with a verdict: well-formed, two lists while the back half hangs off its own head between the cut and the last weave, or cycle.

The four phases, each a strip label at the top:

  1. Find the middle. slow and fast both start on the head and step 1× and 2× while fast.next and fast.next.next exist, so slow stops on the last node of the front half — the longer half when n is odd.
  2. Cut. second = slow.next, read before the write, then slow.next = ∅. The walk from the head is short now, on purpose.
  3. Reverse the back half. The classic nxt = cur.next; cur.next = prev; prev = cur; cur = nxt, one flip per node, the run arcing backward as it goes.
  4. Weave. a on the front, b on the reversed back: save a.next and b.next, write a.next = b, write b.next = an, advance both; stop when b runs out. Whatever front node is left over is already in place.

Two controls, one per classic failure.

Cut: forgotten is the one with no error. The reversal does not care that the front half’s last node still points into it; the weave does not care either; the final b.next = an reads an from a front node that still points backward and closes a cycle. The result reads in the right order and then repeats forever. The walk line calls it before the code could.

Middle: fast = head.next is the habit carried over from cycle detection. On every even length it is indistinguishable from the correct loop; on odd lengths it leaves the back half one node longer than the front, and the weave runs off the end of the front half — an = a.next on ∅ — one write after everything looked fine. On a one-node list it dereferences nil before the first step.

Type your own list (up to twelve values), step through one write at a time, or let it run.

Reuse

src/weave.js is a framework-free ES module:

No rendering or timers in the module; the canvas demo is reference code.

Gotchas