INVARIANT · LINKED LIST · NODES & POINTERS, FROM THE GROUND UP
01
00/01
01 / COVER STEP 06 · LINKED LIST
INVARIANT · STEP 06 · DECK 1 OF 3
NODES AND POINTERS

Before a single interview problem, own the object itself: a node holding a value and a pointer to the next one. This deck builds the linked list from nothing — traverse it, insert and delete anywhere, then add a second pointer for the doubly linked list and reverse it. Every operation is re-routing arrows, animated one pointer at a time, and the capstone is building the whole structure yourself.

1Problems
3Patterns
4Units
4Lectures
← → ↑ ↓  or  W A S D  navigate SPACE next   DOUBLE-CLICK to advance I index   G goto problem   P predict H hide solutions   T close video   F fullscreen
INVARIANT · LINKED LIST · NODES & POINTERS, FROM THE GROUND UP · DECK 1 OF 3
02 / START HERE READ THIS ONE FIRST

HOW THIS DECK WORKS

This is not a list of problems. It is 4 learning units, and every one runs the same four beats. Go in order and the problems stop feeling random.

01 INTROWhat the concept is, and what to watch for
02 VIDEOThe lecture, full-width in theatre mode
03 DRILLS2–4 questions checking the lecture landed
04 PROBLEMSThe sheet problems that concept unlocks

Moving around

← ↑Back a slide — or A / W → ↓Forward — or D / S / Space 2×clickDouble-click the right side to advance, left to go back. A single click never moves the deck. IThe index: every problem, clickable, with your progress GJump straight to a problem by its number FFullscreen

While you study

HHide solutions — blurs code and steps so you try first PPredict mode: call the next step before the animation plays it TClose the video — Esc works too ☐ ★Mark solved, or star to revisit. Both are saved automatically.

1 PROBLEMS · EVERY ONE LINKS TO LEETCODE TO SOLVE

INVARIANT · LINKED LIST · NODES & POINTERS, FROM THE GROUND UP · DECK 1 OF 3
03 / INDEX PRESS I FROM ANYWHERE

INDEX — ALL 1 PROBLEM

Click any problem to jump straight to it. Solved ones turn green. Press I from anywhere to come back here. The number is the sheet's row, not your position — the deck teaches in the order that builds, so you will meet them slightly out of numerical sequence.

FUNDAMENTALS — SINGLY & DOUBLY · 01
SOLVED HAS A LEETCODE LINK
INVARIANT · LINKED LIST · NODES & POINTERS, FROM THE GROUND UP · DECK 1 OF 3
04 / SIGNALS WHEN YOU SEE X, REACH FOR Y

LIST OR ARRAY — AND WHICH LIST

A linked list is a bet: pay O(n) access to win O(1) middle-mutation. These cards are the signals in a statement that say the bet is worth taking — and which flavour of list to reach for.

“MANY INSERTIONS / DELETIONS IN THE MIDDLE”, NO INDEXING NEEDED

a linked list splices in O(1) once you hold the spot; an array shifts O(n)

LINKED LIST — pointer surgery, no shiftinginsert/delete O(1) given the node
“ACCESS THE k-th ELEMENT” / RANDOM ACCESS, BINARY SEARCH

a list has no indices — reaching node k costs a full walk

ARRAY — contiguous, O(1) random accesslist access is O(k)
A NODE HANDED TO YOU, “DELETE IT IN O(1)”

with only next you cannot reach prev; a doubly list can

DOUBLY LINKED LIST — unlink via node->prevO(1) delete given the node
“INSERT / REMOVE AT BOTH ENDS” (a deque)

head and tail pointers make both ends O(1)

DOUBLY LIST with head + tailpush/pop front and back O(1)
“THE FIRST NODE MIGHT CHANGE” (insert/delete at position 0)

special-casing head is where off-by-one bugs live

A DUMMY HEAD node — every position is uniformremoves the head special case
“NO RESIZE, MEMORY SCATTERED”, unknown size up front

a list grows one node at a time without reallocation

LINKED LIST — allocate as you goO(1) growth, O(n) cache-unfriendly
INVARIANT · LINKED LIST · NODES & POINTERS, FROM THE GROUND UP · DECK 1 OF 3
05 / CONSTRAINTS BEFORE YOU WRITE A LINE

READ THE ANSWER OFF THE CONSTRAINTS

The whole cost model of a linked list on one screen. It is not about n so much as about which operation — indexing is dear, splicing is cheap.

n ≤
BUDGET
WHAT THAT BUYS YOU
access node k
O(k)
no indices — you must WALK from head; arrays do this in O(1)
length / search
O(n)
one traversal from head to null — the primitive under everything
insert/delete at head
O(1)
just re-point head — the list's core strength
insert/delete at position k
O(k)
walk to k (O(k)), then splice (O(1))
delete a GIVEN node (doubly)
O(1)
reach prev through node->prev — impossible in a singly list
reverse the whole list
O(n)
one pass; O(1) extra space, no new nodes

GOLD ROWS ARE WHERE LISTS BEAT ARRAYS · ACCESS-BY-INDEX IS THE ONE THING THEY GIVE UP

INVARIANT · LINKED LIST · NODES & POINTERS, FROM THE GROUND UP · DECK 1 OF 3
06 / ROADMAP WHAT YOU ARE ABOUT TO DO

THE WHOLE RUN, 4 UNITS

Four fundamentals, one object. Traverse it, mutate it, add a second pointer, reverse it — then build the whole thing yourself. The interview problems are decks 2 and 3.

UNIT 01

Anatomy & Traversal

▶ 45:173 DRILLSNO SHEET ROW
UNIT 02

Insert & Delete

▶ 56:303 DRILLS1 PROBLEM
UNIT 03

The Doubly Linked List

▶ 64:072 DRILLSNO SHEET ROW
UNIT 04

Reverse a Doubly List

▶ 18:302 DRILLSNO SHEET ROW
INVARIANT · LINKED LIST · NODES & POINTERS, FROM THE GROUND UP · DECK 1 OF 3
07 / WARMUP LOAD THE POINTER MODEL BEFORE UNIT 01 · 1 OF 2

THREE THINGS WORTH HAVING IN MEMORY

DRILL 01 · RECALL

What is the one operation an array does in O(1) that a linked list cannot?

Random access. An array stores elements contiguously, so element k is a single address computation — O(1). A linked list scatters nodes in memory and connects them only by pointers, so the only way to reach node k is to start at head and follow next k times — O(k). That single trade explains everything: lists win when you splice in the middle a lot and never index; arrays win when you index a lot. Binary search, for instance, is pointless on a list because you cannot jump to the middle.

DRILL 02 · RECALL

A singly linked list node holds a value and a next pointer. What does the last node's next point to, and why does it matter?

null. The tail's next is null, and that is precisely what stops a traversal — while (temp != nullptr) temp = temp->next walks until it falls off the end. Get this wrong (a dangling pointer, or a self-reference) and the walk either crashes or loops forever. Half of all linked-list bugs are a null that was not checked or not set: dereferencing temp->next when temp is already null is the single most common crash.

INVARIANT · LINKED LIST · NODES & POINTERS, FROM THE GROUND UP · DECK 1 OF 3
08 / WARMUP LOAD THE POINTER MODEL BEFORE UNIT 01 · 2 OF 2

THREE THINGS WORTH HAVING IN MEMORY

DRILL 01 · RECALL

Why do so many linked-list solutions start by creating a dummy (sentinel) head node?

It erases the head special case. Without a dummy, inserting or deleting at position 0 has to update head itself, so you write a separate branch — and that branch is where off-by-one and null bugs breed. A dummy node sitting before the first real node means every position, including the front, has a genuine prev to splice against; you return dummy->next at the end. One uniform code path instead of two is why it appears in Design Linked List, Remove Nth Node, Merge, and half of deck 2.

INVARIANT · LINKED LIST · NODES & POINTERS, FROM THE GROUND UP · DECK 1 OF 3
09 / INTRO UNIT 01 · Anatomy & Traversal

UNIT 01 — Anatomy & Traversal

A linked list is the simplest pointer structure: a chain of nodes, each holding a value and a next pointer to the following node, ending when next is null. There are no indices — the only handle you get is head, and everything (length, search, printing) is one traversal: start at head and follow next until null, doing your work at each node.

THE QUESTION THIS LECTURE ANSWERS

HOW DO YOU DO ANYTHING TO A LIST YOU CAN ONLY ENTER FROM ITS head?

NODEheadnextnull TERMINATORTRAVERSAL
WHAT TO WATCH FOR
  • 01A NODE = { value, next }. THE LIST IS JUST THE head POINTER TO THE FIRST NODE
  • 02THE TAIL'S next IS null — THAT SENTINEL IS WHAT ENDS EVERY WALK
  • 03TRAVERSAL: temp = head; WHILE (temp) { work; temp = temp->next; }
  • 04THERE IS NO RANDOM ACCESS — REACHING NODE k COSTS A k-STEP WALK, O(k)
INVARIANT · LINKED LIST · NODES & POINTERS, FROM THE GROUND UP · DECK 1 OF 3
10 / VIDEO UNIT 01 · Anatomy & Traversal

L1. Introduction to LinkedList | Traversal | Length | Search an Element

STRIVER A2Z
Anatomy & Traversal
RUNTIME 45:17
AFTER THIS → 3 DRILLS · CONCEPT UNIT
INVARIANT · LINKED LIST · NODES & POINTERS, FROM THE GROUND UP · DECK 1 OF 3
11 / DRILL UNIT 01 · Anatomy & Traversal · 1 OF 2

CHECK — CAN YOU ANSWER IT WITHOUT LOOKING BACK?

DRILL 01 · RECALL

To compute the length of a singly linked list, what is the loop, and where does it stop?

Walk until temp itself is null. Starting at head and looping while (temp != nullptr), you count each node and advance; the loop naturally ends when temp steps past the tail to null. The common off-by-one is stopping at temp->next != null, which never counts the last node. The condition is on temp, not temp->next — that distinction is the whole difference between a correct length and one that is short by one.

DRILL 02 · TRACE

On the list 8 → 3 → 7 → 2 → null, searching for 7 with a traversal, how many nodes does temp visit before it finds it?

Three visits. temp starts at node 0 (value 8), moves to node 1 (value 3), then node 2 (value 7) where the match is found — the third node examined, at index 2. There is no shortcut: search on a linked list is inherently linear because you cannot binary-search a structure you can only walk forward one node at a time. The MECHANISM slide animates temp hopping node to node until the value lights up.

INVARIANT · LINKED LIST · NODES & POINTERS, FROM THE GROUND UP · DECK 1 OF 3
12 / DRILL UNIT 01 · Anatomy & Traversal · 2 OF 2

CHECK — CAN YOU ANSWER IT WITHOUT LOOKING BACK?

DRILL 01 · TRANSFER

Why can't you binary-search a sorted linked list in O(log n), the way you would a sorted array?

Finding the middle is O(n), so the log-n advantage evaporates. Binary search's power comes from jumping to a[mid] in O(1); on a list, locating that midpoint means walking half the nodes, and you would pay O(n) at every level for a total of O(n log n) — worse than a plain O(n) scan. This is the deepest consequence of “no random access”: entire algorithm families (binary search, quickselect) simply do not port to lists, which is why list problems lean on pointers — fast/slow, dummy, reverse — instead.

INVARIANT · LINKED LIST · NODES & POINTERS, FROM THE GROUND UP · DECK 1 OF 3
13 / MECHANISM UNIT 01 · TRAVERSE · CODE MIRRORED

ONE WALK FROM head UNTIL null

Everything in this topic is built on a single loop: point temp at the head and follow temp = temp->next until it becomes null, doing your work at each node. Length is a counter, search is a comparison, printing is a read. There is no random access — you cannot jump to node k, you must walk to it — which is the whole trade linked lists make versus arrays.

RE-ROUTING THE ARROWS
CODE MIRROR
INVARIANT · LINKED LIST · NODES & POINTERS, FROM THE GROUND UP · DECK 1 OF 3
14 / INTRO UNIT 02 · Insert & Delete

UNIT 02 — Insert & Delete

Insertion and deletion are why linked lists exist: both are O(1) pointer surgery once you hold the right spot, with no shifting. To insert, walk prev to the node before the gap, then new->next = prev->next before prev->next = new. To delete, bypass the victim with prev->next = victim->next and free it. A dummy head makes position 0 behave like any other.

THE QUESTION THIS LECTURE ANSWERS

HOW DO YOU ADD OR REMOVE A NODE ANYWHERE WITHOUT SHIFTING THE REST?

prev POINTERSPLICEBYPASSDUMMY HEADdelete / free
WHAT TO WATCH FOR
  • 01INSERT ORDER IS SACRED: new->next = prev->next, THEN prev->next = new
  • 02DELETE: victim = prev->next; prev->next = victim->next; delete victim;
  • 03A DUMMY head NODE REMOVES THE 'INSERT/DELETE AT POSITION 0' SPECIAL CASE
  • 04TO REACH POSITION k, STOP prev AT k−1 — OFF-BY-ONE LIVES HERE
INVARIANT · LINKED LIST · NODES & POINTERS, FROM THE GROUND UP · DECK 1 OF 3
15 / VIDEO UNIT 02 · Insert & Delete

L2. Deletion and Insertion in LL | 8 Problems

STRIVER A2Z
Insert & Delete
RUNTIME 56:30
AFTER THIS → 3 DRILLS · PROBLEM #01
INVARIANT · LINKED LIST · NODES & POINTERS, FROM THE GROUND UP · DECK 1 OF 3
16 / DRILL UNIT 02 · Insert & Delete · 1 OF 2

CHECK — CAN YOU ANSWER IT WITHOUT LOOKING BACK?

DRILL 01 · BUG

This insertion at a middle position loses part of the list. Which line ordering is wrong?

Node* node = new Node(val);
prev->next = node;
node->next = prev->next;            // too late — prev->next is now node

The two assignments are in the wrong order. Setting prev->next = node first overwrites the link to the rest of the list; then node->next = prev->next reads the value you just changed, so node ends up pointing at itself and everything after the insertion point is orphaned. The rule is absolute: link the new node outward first (node->next = prev->next), then relink prev. Order is the entire difficulty of pointer surgery.

DRILL 02 · RECALL

After prev->next = victim->next deletes a node from a singly list in C++, what must you not forget?

delete victim. Re-pointing prev->next makes the victim unreachable from the list, but the object still occupies heap memory until you explicitly free it — a leak in C++. Capture the pointer (victim = prev->next) before the bypass so you still have a handle to delete. Languages with garbage collection (Java, Python) reclaim it automatically, but the interviewer asking in C++ is testing exactly this discipline.

INVARIANT · LINKED LIST · NODES & POINTERS, FROM THE GROUND UP · DECK 1 OF 3
17 / DRILL UNIT 02 · Insert & Delete · 2 OF 2

CHECK — CAN YOU ANSWER IT WITHOUT LOOKING BACK?

DRILL 01 · TRANSFER

How does a dummy head node simplify deleteAtIndex(0) — removing the first real node?

The dummy gives position 0 a real predecessor. Without it, deleting the first node means special-casing head = head->next and propagating the new head; with a dummy sentinel in front, prev for index 0 is simply the dummy, so prev->next = victim->next handles the front exactly like the middle. You return dummy->next as the real head at the end. One code path for every index is why Design Linked List and so many deck-2 problems open with Node* dummy = new Node().

INVARIANT · LINKED LIST · NODES & POINTERS, FROM THE GROUND UP · DECK 1 OF 3
18 / MECHANISM UNIT 02 · INSERT · CODE MIRRORED

LINK THE NEW NODE OUT BEFORE YOU RELINK prev

Insertion is pure pointer surgery and the order of two assignments is the whole game. Walk prev to the node just before the gap, then new->next = prev->next first, and only then prev->next = new. Reverse those two and you overwrite the link to the rest of the list before the new node has grabbed it — losing everything after the insertion point. A dummy head node removes the “insert at position 0” special case.

RE-ROUTING THE ARROWS
CODE MIRROR
INVARIANT · LINKED LIST · NODES & POINTERS, FROM THE GROUND UP · DECK 1 OF 3
19 / MECHANISM UNIT 02 · DELETE · CODE MIRRORED

BYPASS THE NODE, THEN FREE IT

Deletion is insertion's mirror: walk prev to the node before the target, remember victim = prev->next, then prev->next = victim->next to route the arrow around it. In C++ you then delete victim to free the memory — forgetting it leaks. Once the arrow jumps over the victim, nothing points to it, so it is unreachable; the dummy head again saves you from special-casing deletion of the first node.

RE-ROUTING THE ARROWS
CODE MIRROR
INVARIANT · LINKED LIST · NODES & POINTERS, FROM THE GROUND UP · DECK 1 OF 3
20 / PROBLEM #01 · MUTATE · MED

Design Linked List

MED mutate ▶ SOLVE ON LEETCODE
SIGNAL — WHAT GIVES IT AWAY

“Design / implement a linked list” with get, addAtHead, addAtTail, addAtIndex and deleteAtIndex. It is the capstone of the fundamentals: every operation is a traversal plus a splice, and a dummy head makes all of them uniform.

INTUITION

Keep a dummy head and a size counter. get(i) walks i steps past the dummy. addAtIndex(i) and deleteAtIndex(i) both walk prev to the node at index i − 1 (starting from the dummy, so index 0 is not special) and then splice or bypass. addAtHead / addAtTail are just addAtIndex(0) and addAtIndex(size).

STEPS
  1. Store a dummy head node and an int size
  2. get(i): bounds-check; walk i nodes past the dummy; return its value
  3. addAtIndex(i): if 0 ≤ i ≤ size, walk prev to index i−1 from the dummy, splice a new node, size++
  4. deleteAtIndex(i): if 0 ≤ i < size, walk prev to index i−1, bypass and free the victim, size--
  5. addAtHead = addAtIndex(0); addAtTail = addAtIndex(size)
BRUTEO(1) build
OPTIMALO(k) per op
↕ SCROLL
// A dummy head makes every index — including 0 — a uniform splice.
class MyLinkedList {
    struct Node { int val; Node* next; Node(int v): val(v), next(nullptr) {} };
    Node* dummy;
    int sz;
public:
    MyLinkedList(): dummy(new Node(0)), sz(0) {}

    int get(int index) {
        if (index < 0 || index >= sz) return -1;
        Node* cur = dummy->next;
        while (index--) cur = cur->next;      // walk index steps
        return cur->val;
    }
    void addAtHead(int val) { addAtIndex(0, val); }
    void addAtTail(int val) { addAtIndex(sz, val); }

    void addAtIndex(int index, int val) {
        if (index < 0 || index > sz) return;
        Node* prev = dummy;
        while (index--) prev = prev->next;    // stop prev at index-1
        Node* node = new Node(val);
        node->next = prev->next;              // link OUT first
        prev->next = node;                    // then relink prev
        sz++;
    }
    void deleteAtIndex(int index) {
        if (index < 0 || index >= sz) return;
        Node* prev = dummy;
        while (index--) prev = prev->next;
        Node* victim = prev->next;
        prev->next = victim->next;            // bypass
        delete victim;                        // free
        sz--;
    }
};
TIMEO(k) per opget/add/delete at index k walk k nodes; head ops are O(1)
SPACEO(n)one node per stored element, plus the dummy
TRAP

Off-by-one on where prev stops, and missing bounds checks. Because the walk starts at the dummy, looping index times lands prev at index i − 1 — exactly where you splice; starting from the real head instead shifts everything by one. And addAtIndex permits index == size (append) while get and deleteAtIndex require index < size — mixing up the two boundary conditions is the most common way this passes the samples and fails the edge tests.

INVARIANT · LINKED LIST · NODES & POINTERS, FROM THE GROUND UP · DECK 1 OF 3
SOLUTION #01 · DESIGN LINKED LIST

L2. Deletion and Insertion in LL | 8 Problems

The walkthrough for #01 Design Linked List. Watch it, then go straight back and write it yourself.

SOLUTION WALKTHROUGH
L2. Deletion and Insertion in LL | 8 Problems
RUNTIME 56:30
INVARIANT · LINKED LIST · NODES & POINTERS, FROM THE GROUND UP · DECK 1 OF 3
21 / INTRO UNIT 03 · The Doubly Linked List

UNIT 03 — The Doubly Linked List

A doubly linked list adds a second pointer, prev, to every node, so each node knows both neighbours. That buys two things a singly list cannot do: O(1) deletion of a node you already hold (you can reach its prev), and clean backward traversal. The cost is one extra pointer per node and the discipline of maintaining four links on every insert.

THE QUESTION THIS LECTURE ANSWERS

WHAT DOES A SECOND POINTER PER NODE BUY, AND WHAT DOES IT COST?

prev POINTERFOUR LINKSBIDIRECTIONALO(1) NODE DELETEDEQUE
WHAT TO WATCH FOR
  • 01EACH NODE NOW HOLDS { prev, value, next } — IT CAN LOOK BOTH WAYS
  • 02INSERT TOUCHES FOUR LINKS: new->next, new->prev, prev->next, cur->prev
  • 03O(1) DELETE GIVEN THE NODE — REACH prev THROUGH node->prev, NO WALK
  • 04A HEAD + TAIL POINTER MAKES BOTH ENDS O(1) — THE BASIS OF A DEQUE
INVARIANT · LINKED LIST · NODES & POINTERS, FROM THE GROUND UP · DECK 1 OF 3
22 / VIDEO UNIT 03 · The Doubly Linked List

L3. Introduction to Doubly LinkedList | Insertions and Deletions

STRIVER A2Z
The Doubly Linked List
RUNTIME 64:07
AFTER THIS → 2 DRILLS · CONCEPT UNIT
INVARIANT · LINKED LIST · NODES & POINTERS, FROM THE GROUND UP · DECK 1 OF 3
23 / DRILL UNIT 03 · The Doubly Linked List

CHECK — CAN YOU ANSWER IT WITHOUT LOOKING BACK?

DRILL 01 · RECALL

Inserting a node between prev and cur in a doubly linked list sets how many pointers, and which?

Four links. The new node needs both of its own pointers set (new->next = cur, new->prev = prev) and both neighbours must point back to it (prev->next = new, cur->prev = new). Set the new node's two links first, then relink the neighbours. Miss any one — most often a prev back-link — and the list is subtly corrupt: forward iteration works, backward iteration walks into a hole. The MECHANISM slide highlights all four re-routes in order.

DRILL 02 · TRANSFER

Why can a doubly linked list delete a node handed to you in O(1), while a singly list needs O(n)?

The back-pointer gives you prev for free. Deleting a node means prev->next = node->next, so you need prev. A doubly node already stores it (node->prev), making the unlink O(1) — node->prev->next = node->next; node->next->prev = node->prev. A singly node has no way back, so finding prev means re-walking from head, which is O(n). This single capability is why LRU/LFU caches and browser-history structures are built on doubly lists.

INVARIANT · LINKED LIST · NODES & POINTERS, FROM THE GROUND UP · DECK 1 OF 3
24 / MECHANISM UNIT 03 · DOUBLY · CODE MIRRORED

FOUR LINKS, OR THE BACK-CHAIN BREAKS SILENTLY

A doubly linked list adds a prev pointer, so every node can look both ways — which buys O(1) deletion given the node and a clean reverse, at the cost of one more pointer per node. Insertion now touches four links: new->next, new->prev, prev->next, and cur->prev. Miss a back-link and the forward walk still looks perfect while the reverse walk quietly breaks — the classic doubly-list bug.

RE-ROUTING THE ARROWS
CODE MIRROR
INVARIANT · LINKED LIST · NODES & POINTERS, FROM THE GROUND UP · DECK 1 OF 3
25 / INTRO UNIT 04 · Reverse a Doubly List

UNIT 04 — Reverse a Doubly List

Reversing a doubly linked list is the payoff of the prev pointer. Since each node already knows both neighbours, reversal is just: walk once and swap every node's prev and next. After the pass, every arrow has flipped, so the old tail — the node that had no next — now has no prev, making it the new head. O(n) time, O(1) space, no new nodes.

THE QUESTION THIS LECTURE ANSWERS

HOW DO YOU REVERSE A LIST WITHOUT MOVING A SINGLE NODE IN MEMORY?

SWAP prev/nextIN-PLACENEW head = OLD tailO(1) SPACEONE PASS
WHAT TO WATCH FOR
  • 01REVERSAL IS NOT MOVING NODES — IT IS FLIPPING THE POINTERS BETWEEN THEM
  • 02PER NODE: swap(node->prev, node->next), THEN ADVANCE ALONG THE OLD next
  • 03AFTER ADVANCING, node = node->prev (BECAUSE prev/next JUST SWAPPED)
  • 04THE OLD TAIL BECOMES head; RETURN IT — DO NOT return THE OLD head
INVARIANT · LINKED LIST · NODES & POINTERS, FROM THE GROUND UP · DECK 1 OF 3
26 / VIDEO UNIT 04 · Reverse a Doubly List

L4. Reverse a DLL | Multiple Approaches

STRIVER A2Z
Reverse a Doubly List
RUNTIME 18:30
AFTER THIS → 2 DRILLS · CONCEPT UNIT
INVARIANT · LINKED LIST · NODES & POINTERS, FROM THE GROUND UP · DECK 1 OF 3
27 / DRILL UNIT 04 · Reverse a Doubly List

CHECK — CAN YOU ANSWER IT WITHOUT LOOKING BACK?

DRILL 01 · RECALL

The core step of reversing a doubly linked list, at each node, is:

Swap the node's two pointers. Because a doubly node holds both prev and next, reversing the whole list is nothing more than exchanging those two fields at every node — no allocation, no data movement. The only subtlety is advancing: after the swap, the direction you want to go (the old next) now lives in node->prev, so you step with node = node->prev. It is one of the most elegant O(1)-space operations in the topic.

DRILL 02 · TRACE

Reversing 5 ⇄ 8 ⇄ 12 ⇄ 20, which node becomes the new head, and why?

20, the old tail. Before reversal, 20 is the tail: it has a prev (12) but no next. After swapping every node's pointers, that relationship inverts — 20 now has a next (12) but no prev, and “no prev” is exactly what makes a node the head. Returning the old head (5) instead of the new one is the classic mistake; 5 has become the tail. The MECHANISM slide moves the head and tail labels to opposite ends at the final step.

INVARIANT · LINKED LIST · NODES & POINTERS, FROM THE GROUND UP · DECK 1 OF 3
28 / MECHANISM UNIT 04 · REVERSEDLL · CODE MIRRORED

SWAP prev/next AT EVERY NODE — TAIL BECOMES head

Because a doubly node already knows both neighbours, reversing it is startlingly simple: walk once and swap(node->prev, node->next) at each node. After the pass every arrow has flipped, so the node that used to have no next (the tail) now has no prev — which is exactly what head means. Return the old tail. O(n) time, O(1) space, no new nodes.

RE-ROUTING THE ARROWS
CODE MIRROR
INVARIANT · LINKED LIST · NODES & POINTERS, FROM THE GROUND UP · DECK 1 OF 3
29 / RECALL RETRIEVAL, NOT RECOGNITION

PICK THE STRUCTURE FROM THE OPERATION MIX

DRILL 01 · TRANSFER

You are storing a playlist where users constantly insert and remove songs in the middle, and you never need to jump to “song number 500”. Array or linked list?

Linked list. The access pattern is all middle-mutation and no indexing, which is exactly the list's sweet spot: splicing a node in or out is a couple of pointer writes, while an array would shift every later element on each edit — O(n) per operation. Flip the requirement to “jump to song 500 constantly” and the answer flips to array. Matching the data structure to the operation mix, not to habit, is the actual skill this deck is building toward.

DRILL 02 · RECALL

A doubly linked list costs one extra pointer per node over a singly list. What two capabilities does that buy?

O(1) delete-given-a-node and two-way traversal. The extra prev pointer means a node knows its predecessor, so you can unlink it without walking from the head to find prev — impossible in a singly list, where deleting a handed-in node is O(n). It also lets you iterate backward and reverse by a simple prev/next swap. The cost is the extra pointer's memory and the discipline of maintaining both link directions on every edit — which is why the LRU cache (deck 3) is built on a doubly list.

INVARIANT · LINKED LIST · NODES & POINTERS, FROM THE GROUND UP · DECK 1 OF 3
30 / TRAPS PLAUSIBLE, WRONG, AND SILENT

SIX WAYS TO BE PLAUSIBLY WRONG

Pointer bugs do not throw at the line you wrote them — they surface later, on an edge case, as a lost tail or a broken back-chain. Every one of these compiles.

OVERWRITING prev->next BEFORE new->next

On insertion you must set new->next = prev->next first, then prev->next = new. Do it the other way and you overwrite the only link to the rest of the list before the new node has grabbed it — everything after the insert point is lost.

DEREFERENCING A null POINTER

temp->next when temp is already null crashes. Empty lists, single-node lists and the tail are the edge cases; always test the loop on a 0- and 1-node list before trusting it.

LEAKING THE DELETED NODE (C++)

Bypassing a node with prev->next = victim->next unlinks it but does not free it. In C++ you must delete victim; forgetting it is a memory leak the judge may not catch but an interviewer will.

DOUBLY LIST: A FORGOTTEN BACK-LINK

Insertion/deletion in a doubly list touches links in both directions. Set the next chain but forget a prev, and the forward walk looks perfect while the reverse walk is silently broken — a bug that hides until someone iterates backward.

UPDATING head WITHOUT RETURNING IT

When an operation can change the first node (insert/delete at position 0), the new head must be propagated back to the caller. A local reassignment that never returns leaves the caller pointing at a stale or freed node. The dummy-head pattern sidesteps this.

WALKING TO THE WRONG POSITION (off-by-one)

To insert/delete at position k you stop prev at k − 1, not k. Looping k times from the dummy versus from the real head shifts everything by one — check whether your start node is the dummy or the first real node.

INVARIANT · LINKED LIST · NODES & POINTERS, FROM THE GROUND UP · DECK 1 OF 3
31 / CHEATSHEET REVISION SURFACE

ONE SCREEN, THE WHOLE DECK

The cost of every operation, once. The right-hand column is when to reach for it — and the O(k) rows are the price of having no indices.

ALGORITHM
TIME
SPACE
REACH FOR IT WHEN
Traverse / length / search
O(n)
O(1)
one walk from head to null
Access the k-th node
O(k)
O(1)
no indices — walk to it; arrays do this in O(1)
Insert / delete at head
O(1)
O(1)
just re-point head (use a dummy)
Insert / delete at tail
O(1)*
O(1)
*O(1) with a tail pointer, else O(n)
Insert / delete at position k
O(k)
O(1)
walk to k−1, then splice
Delete a GIVEN node
O(1)
O(1)
doubly only — reach prev via node->prev
Reverse (singly)
O(n)
O(1)
prev/curr/next re-link, one pass (deck 2)
Reverse (doubly)
O(n)
O(1)
swap prev/next at every node
INVARIANT · LINKED LIST · NODES & POINTERS, FROM THE GROUND UP · DECK 1 OF 3
32 / CLOSE STEP 06 · DECK 1 OF 3

THE OBJECT, OWNED

Once nodes and pointers are automatic — traverse, splice, bypass, swap — the interview problems stop being about linked lists and start being about which pointer trick (fast/slow, dummy, reverse) the statement is quietly asking for. That is decks 2 and 3.

00%
OF THIS DECK SOLVED
← ALL TOPICSDECK 2 · MEDIUM →STEP 05 · STRINGS

Lectures are Striver's A2Z linked-list playlist (L1–L4). The single sheet problem here is Design Linked List; the medium and hard problems are decks 2 and 3.

INVARIANT · LINKED LIST · NODES & POINTERS, FROM THE GROUND UP · DECK 1 OF 3
■ TOO SMALL TO READ
1280×720
INVARIANT · STEP 06 · DECK 1 OF 3

This one needs a laptop

Not a preference — an arithmetic one. Every slide is a fixed 1280 × 720 stage: a graph animating beside the code that drives it, with the problems laid out two columns wide. It scales as a single piece, so on a screen this size the body text comes out around 4px tall.

Shrinking it further would not help, and rebuilding it to reflow would mean losing the thing that makes it worth reading.

YOUR SCREEN0 × 0
NEEDED1060 × 610
WHAT IS WAITING ON THE LAPTOP
WATCH IT RUN, THEN RUN IT FROM MEMORY
Your progress is saved per device, so anything you tick on the laptop will be waiting there.