Don't memorize the linked list — watch the pointers move. Each node holds a value and an arrow to the next one; there's no block of memory, just a chain you follow from the head. Insert at the front in O(1), delete by re-pointing around a node, and reverse the whole thing by flipping every arrow.
nodes · next-pointers · insert · delete · reverse
NODE
A value plus a pointer to the next node. The building block.
HEAD
The pointer to the first node — your only handle on the list.
NEXT
Each node's arrow to the following one; the last points to null.
O(1) INSERT
Re-point a couple of arrows — no shifting, unlike an array.
linked-list.sim — insert · delete · reverse
Ready
A singly linked list: three nodes, each pointing to the next, the last to null. Press Step to run through insert-at-head, insert-at-tail, delete, and reverse — one pointer move at a time.
3
Length
—
Last op cost
Pointers instead of a block
An array stores its elements side by side, so element k is a jump away — but inserting in the middle means shifting everything after it. A linked list gives that up for flexibility: nodes live anywhere in memory, threaded by pointers. To insert or delete you just rewire a couple of arrows — no shifting — but to reach the k-th node you have to walk there from the head.
01
Insert at head
Make the new node's next point at the current head, then move head to the new node. Two pointer writes — O(1).
02
Insert at tail
Walk to the last node and point its next at the new node. O(n) — unless you keep a tail pointer, then O(1).
03
Delete a node
Find the node before the target and re-point its next past the target. The node is unlinked — no gap to fill, no shifting.
04
Reverse
Walk with prev, curr, next and flip each arrow to point backward. The old tail becomes the new head. O(n) time, O(1) space.
Insert / delete at position
O(1)
Access k-th node
O(n)
Search
O(n)
Space
O(n)
Linked lists are the backbone of stacks, queues, adjacency lists and the recency list inside an LRU cache. The cost is the pointer per node and poor cache locality — jumping around memory is slower than scanning a contiguous array — which is why a dynamic array is the better default when you mostly index and iterate.
SOLVE IT YOURSELF
Solve it: reverse a linked list
This one is yours to write — in Python or TypeScript, running for real in your browser. Edit the stub below, hit Run (or ⌘/Ctrl + Enter), and watch the hidden tests. Stuck? the hints are below and Reveal solution is one click away.
YOUR TASK
The scaffold builds a singly linked list from a list of values and flattens it back for checking — your job is the middle part: reverse the list in place by re-pointing each node, using three pointers (prev, cur, next). Set head to the new front. O(n), no extra list.
HINTS — 4 IDEAS
Reversing means every next pointer flips to point at the node before it.
Walk with cur, keeping prev as the node already reversed behind you.
Each step: remember nxt = cur.next, set cur.next = prev, then advance prev = cur and cur = nxt.
When cur falls off the end, prev is the new head — assign it to head.
CPython · WebAssembly✓ Solved
1
1
Check yourself
1 · Why is inserting at the head of a linked list O(1)?
Two pointer writes and you're done — nothing after it has to move, unlike an array insert.
2 · What is the cost of reaching the k-th node?
There's no random access; you follow next-pointers from the head, so reaching position k costs k steps.
3 · How do you reverse a singly linked list in O(1) space?
Three references and one pass — flip every arrow to point at the previous node; the old tail becomes the new head.
Questions
Singly vs doubly linked list?
A singly linked list has one pointer per node (next). A doubly linked list adds a prev pointer too, so you can walk backward and delete a node in O(1) given only that node — at the cost of an extra pointer per node. Doubly linked lists power things like LRU caches and browser history.
Why not always use an array?
Arrays win on indexed access and cache-friendly iteration, but inserting or deleting in the middle is O(n) because everything shifts. Linked lists make those edits O(1) at the cost of no random access and extra pointer memory. Pick based on which operations dominate.
How do you detect a cycle in a linked list?
Floyd's tortoise-and-hare: advance one pointer by one node and another by two. If they ever meet, there's a cycle; if the fast one hits null, there isn't. It runs in O(n) time and O(1) space — a classic interview follow-up.
You just rewired a list.
Insert by re-pointing, delete by skipping, reverse by flipping. The pointer-based structure under stacks, queues and caches.