π Linked Lists: Advanced Operations
The Train Yard Adventure
Imagine youβre the manager of a magical train yard. Each train car (node) is connected to the next by a special hook (pointer). Today, youβll learn the secret tricks that master train conductors use to reorganize, merge, and transform their trains!
π Our Universal Analogy: The Train Yard
Throughout this guide:
- Node = A train car carrying cargo (data)
- Pointer/Next = The hook connecting cars together
- Head = The engine at the front
- Null = End of the track (no more cars)
class Node {
constructor(val) {
this.val = val;
this.next = null;
}
}
1. Merging Two Sorted Lists π
The Story
Two trains arrive at your yard, each already organized from smallest to biggest cargo numbers. Your job? Combine them into ONE perfectly sorted train!
The Magic Trick
Use a dummy engine at the front. Compare the first cars of both trains, attach the smaller one, then move forward. Repeat!
graph TD A[Start with Dummy] --> B{Compare Front Cars} B -->|L1 smaller| C[Attach L1's car] B -->|L2 smaller| D[Attach L2's car] C --> E[Move L1 forward] D --> F[Move L2 forward] E --> B F --> B B -->|One train empty| G[Attach remaining cars] G --> H[Return dummy.next]
The Code
function mergeTwoLists(l1, l2) {
let dummy = new Node(0);
let current = dummy;
while (l1 && l2) {
if (l1.val <= l2.val) {
current.next = l1;
l1 = l1.next;
} else {
current.next = l2;
l2 = l2.next;
}
current = current.next;
}
current.next = l1 || l2;
return dummy.next;
}
Example
Train 1: 1 β 3 β 5 Train 2: 2 β 4 β 6 Result: 1 β 2 β 3 β 4 β 5 β 6 β¨
Why it works: We never go backwards! Each comparison takes the smallest available car.
2. Sort List π
The Story
A messy train arrives with cars in random order! You need to sort it, but hereβs the catch: you can only see one car at a time and must work efficiently.
The Secret: Merge Sort
- Split the train in half using the slow/fast pointer trick
- Sort each half (recursively)
- Merge the sorted halves
graph TD A[4β2β1β3] --> B[Split in half] B --> C[4β2] B --> D[1β3] C --> E[Split] D --> F[Split] E --> G[4] E --> H[2] F --> I[1] F --> J[3] G --> K[Merge: 2β4] H --> K I --> L[Merge: 1β3] J --> L K --> M[Final Merge: 1β2β3β4] L --> M
Finding the Middle
function getMiddle(head) {
let slow = head;
let fast = head.next;
while (fast && fast.next) {
slow = slow.next;
fast = fast.next.next;
}
return slow;
}
Complete Sort
function sortList(head) {
if (!head || !head.next) return head;
let mid = getMiddle(head);
let right = mid.next;
mid.next = null;
let leftSorted = sortList(head);
let rightSorted = sortList(right);
return mergeTwoLists(leftSorted, rightSorted);
}
Example
Before: 4 β 2 β 1 β 3 After: 1 β 2 β 3 β 4 β¨
3. Intersection of Two Lists βοΈ
The Story
Two trains start from different stations but join at the same car later! Find where they meet.
The Clever Trick
If Train A finishes, jump to Train Bβs start. If Train B finishes, jump to Train Aβs start. Theyβll meet at the intersection!
graph TD A[Start both pointers] --> B{Both reach same node?} B -->|No| C[Move each forward] C --> D{Pointer reached end?} D -->|Yes| E[Jump to other list's head] D -->|No| B E --> B B -->|Yes or both null| F[Return intersection]
The Code
function getIntersection(headA, headB) {
if (!headA || !headB) return null;
let pA = headA;
let pB = headB;
while (pA !== pB) {
pA = pA ? pA.next : headB;
pB = pB ? pB.next : headA;
}
return pA;
}
Why This Works
Math magic! If A has length a + c and B has length b + c (where c is shared), then:
- Pointer A travels:
a + c + b - Pointer B travels:
b + c + a - Same total = they meet at intersection!
Example
A: 1 β 2 β
6 β 7 β null
B: 3 β 4 β 5 β
Intersection: Node 6 β¨
4. Linked List Partitioning π¦
The Story
You need to rearrange a train so all cars with numbers less than X come before cars with numbers X or greater. Order within groups doesnβt matter!
The Approach
Create two temporary trains:
- Small train: All cars < X
- Big train: All cars >= X
Then connect them!
graph TD A[Original: 1β4β3β2β5β2] --> B[Partition around X=3] B --> C[Small: 1β2β2] B --> D[Big: 4β3β5] C --> E[Connect: 1β2β2β4β3β5] D --> E
The Code
function partition(head, x) {
let smallHead = new Node(0);
let bigHead = new Node(0);
let small = smallHead;
let big = bigHead;
while (head) {
if (head.val < x) {
small.next = head;
small = small.next;
} else {
big.next = head;
big = big.next;
}
head = head.next;
}
big.next = null;
small.next = bigHead.next;
return smallHead.next;
}
Example
Before: 1 β 4 β 3 β 2 β 5 β 2 (X = 3) After: 1 β 2 β 2 β 4 β 3 β 5 β¨
5. Odd Even Linked List π’
The Story
Reorganize your train so cars at odd positions (1st, 3rd, 5thβ¦) come first, followed by cars at even positions (2nd, 4th, 6thβ¦).
The Trick
Use two pointers to build two separate chains, then join them!
graph TD A[1β2β3β4β5] --> B[Separate by position] B --> C[Odd: 1β3β5] B --> D[Even: 2β4] C --> E[Join: 1β3β5β2β4] D --> E
The Code
function oddEvenList(head) {
if (!head || !head.next) return head;
let odd = head;
let even = head.next;
let evenHead = even;
while (even && even.next) {
odd.next = even.next;
odd = odd.next;
even.next = odd.next;
even = even.next;
}
odd.next = evenHead;
return head;
}
Example
Before: 1 β 2 β 3 β 4 β 5 Odd positions: 1 β 3 β 5 Even positions: 2 β 4 After: 1 β 3 β 5 β 2 β 4 β¨
6. Reorder List π
The Story
Transform L0 β L1 β ... β Ln into L0 β Ln β L1 β Ln-1 β L2 β ...
Itβs like shuffling cards: take from the top, then the bottom, alternating!
The Three Steps
- Find the middle (slow/fast pointers)
- Reverse the second half
- Weave the two halves together
graph TD A[1β2β3β4β5] --> B[Find Middle] B --> C[First: 1β2β3] B --> D[Second: 4β5] D --> E[Reverse: 5β4] C --> F[Weave together] E --> F F --> G[1β5β2β4β3]
The Code
function reorderList(head) {
if (!head || !head.next) return;
// Find middle
let slow = head, fast = head;
while (fast.next && fast.next.next) {
slow = slow.next;
fast = fast.next.next;
}
// Reverse second half
let prev = null, curr = slow.next;
slow.next = null;
while (curr) {
let next = curr.next;
curr.next = prev;
prev = curr;
curr = next;
}
// Weave together
let first = head, second = prev;
while (second) {
let tmp1 = first.next;
let tmp2 = second.next;
first.next = second;
second.next = tmp1;
first = tmp1;
second = tmp2;
}
}
Example
Before: 1 β 2 β 3 β 4 β 5 After: 1 β 5 β 2 β 4 β 3 β¨
7. Remove Nth Node From End π―
The Story
Remove the car thatβs N positions from the back without counting all cars first!
The Two-Pointer Dance
Send a scout (fast pointer) ahead by N steps. Then move both pointers together. When scout reaches the end, the slow pointer is right before the target!
graph TD A[Start: both at head] --> B[Move fast N steps ahead] B --> C[Move both together] C --> D{Fast at end?} D -->|No| C D -->|Yes| E[Slow is before target] E --> F[Skip the target node]
The Code
function removeNthFromEnd(head, n) {
let dummy = new Node(0);
dummy.next = head;
let fast = dummy;
let slow = dummy;
// Move fast N+1 steps ahead
for (let i = 0; i <= n; i++) {
fast = fast.next;
}
// Move together until fast reaches end
while (fast) {
fast = fast.next;
slow = slow.next;
}
// Skip the nth node
slow.next = slow.next.next;
return dummy.next;
}
Example
List: 1 β 2 β 3 β 4 β 5, N = 2 Remove: 4 (2nd from end) Result: 1 β 2 β 3 β 5 β¨
Why Dummy Node?
Edge case! If we need to remove the first node, having a dummy before it saves us from special handling.
π Key Takeaways
| Operation | Core Technique | Time | Space |
|---|---|---|---|
| Merge Sorted | Dummy + Compare | O(n+m) | O(1) |
| Sort List | Merge Sort | O(n log n) | O(log n) |
| Intersection | Two Pointer Switch | O(n+m) | O(1) |
| Partition | Two Dummy Lists | O(n) | O(1) |
| Odd Even | Index Separation | O(n) | O(1) |
| Reorder | Middle + Reverse + Weave | O(n) | O(1) |
| Remove Nth | Two Pointer Gap | O(n) | O(1) |
π You Did It!
Youβve mastered the 7 advanced linked list operations! These arenβt just algorithmsβtheyβre thinking patterns youβll use everywhere:
- Dummy nodes simplify edge cases
- Two pointers solve problems without extra space
- Divide and conquer handles complex sorting
- Reverse and weave creates elegant transformations
Now go build something amazing! π