Singly vs doubly linked listsCore idea
Singly linked
Each node has a next pointer only. Traversal is one-way.
Doubly linked
Each node has prev and next. Deleting a node you hold a pointer to is easier, but each node costs one extra pointer.
class ListNode {
val: number;
next: ListNode | null;
constructor(val: number, next: ListNode | null = null) {
this.val = val;
this.next = next;
}
}Pattern: reverse a list in placePattern
Reversing a linked list is the single most asked linked list problem. Memorise the three-pointer loop: savenext, flip the arrow, move both pointers forward.
Reversing 1 → 2 → 3, halfway through
function reverseList(head: ListNode | null): ListNode | null {
let prev: ListNode | null = null;
let curr = head;
while (curr) {
const next = curr.next; // save next before rewiring
curr.next = prev; // flip the pointer
prev = curr; // advance prev
curr = next; // advance curr
}
return prev; // prev is the new head
}Pattern: the dummy nodePattern
A dummy node is a fake node placed before the head. It means the real head can be removed or replaced without special-case code. At the end, return dummy.next, which is the true head.
function removeElements(head: ListNode | null, val: number): ListNode | null {
const dummy = new ListNode(0, head);
let curr = dummy;
while (curr.next) {
if (curr.next.val === val) curr.next = curr.next.next;
else curr = curr.next;
}
return dummy.next;
}Pattern: fast and slow pointersPattern
Two pointers, one moving twice as fast, solve cycle detection and “find the middle” in O(1) space. This is Floyd's cycle detection: if the fast pointer ever catches the slow one, there is a cycle.
function hasCycle(head: ListNode | null): boolean {
let slow = head, fast = head;
while (fast && fast.next) {
slow = slow!.next;
fast = fast.next.next;
if (slow === fast) return true;
}
return false;
}More pointer techniquesPattern
Reverse in groups
Reverse K nodes at a time, then stitch each group back onto the rest.
Merge two sorted lists
Walk both lists with a dummy tail and always attach the smaller node.
Find the intersection
Line both lists up by length, then walk together until you reach the shared node.
Partition around a value
Build a “less” list and a “greater” list with dummy heads, then join them.
Common mistakesPitfalls
In the interviewIn the interview
Drawing the boxes and arrows first is normal and expected. It catches most pointer bugs before they happen.
Frequently asked questionsFAQ
Why do interviewers still ask linked lists when they are rarely used in products?
Linked lists test pointer manipulation, careful handling of edge cases, and iterative thinking under time pressure. They are a compact proxy for how you manage references and memory in any language, which is why they persist at every FAANG loop.
Is a linked list faster than an array for insertion?
Only if you already hold a pointer to the insertion point. Inserting at the start or middle of an array costs O(n) because elements shift; a linked list does it in O(1). Searching is still O(n) for lists versus O(1) for array indexing.
How do you know a linked list is sorted?
Walk it once and verify that every next node compares greater than or equal to the current one, using a custom comparator when the values are not numbers. Many merge, partition, and dedupe problems assume monotonic order, so confirming sortedness first keeps the rest of your solution valid.

Now explain linked lists to me out loud
I'll give you interview problems and ask follow-ups, like a real interviewer.

