This page collects battle-tested C++ templates for every major linked-list pattern you’ll see on LeetCode. Each section includes ready-to-use code, the signal phrases that tell you which pattern to reach for, and a quick explanation of the core idea. Bookmark it, copy what you need, and focus your energy on the actual problem logic.

New to Linked Lists? A linked list is a chain of nodes where each node points to the next. Unlike arrays, you can’t jump to index i — you must walk from the head. The tradeoff: O(1) insert/delete at known positions, but O(n) access.

Basic linked list head 1 2 3 null Dummy node pattern dummy 0 head 1 2 3 null

Contents

ListNode Definition

When to use: Every linked-list problem — this is the building block. Know the struct by heart so you never waste time on boilerplate.

Standard Definition

// Standard ListNode definition used in LeetCode
struct ListNode {
    int val;
    ListNode *next;
    ListNode() : val(0), next(nullptr) {}
    ListNode(int x) : val(x), next(nullptr) {}
    ListNode(int x, ListNode *next) : val(x), next(next) {}
};

Alternative Definitions

// Without default constructor
struct ListNode {
    int val;
    ListNode *next;
    ListNode(int x) : val(x), next(nullptr) {}
};

// With pointer initialization
struct ListNode {
    int val;
    ListNode *next;
    ListNode(int x = 0) : val(x), next(nullptr) {}
};

Common Construction Methods

// Method 1: Manual construction
ListNode* createList(vector<int>& values) {
    if (values.empty()) return nullptr;
    
    ListNode* head = new ListNode(values[0]);
    ListNode* cur = head;
    
    for (int i = 1; i < values.size(); ++i) {
        cur->next = new ListNode(values[i]);
        cur = cur->next;
    }
    
    return head;
}

// Method 2: Recursive construction
ListNode* createListRecursive(vector<int>& values, int index) {
    if (index >= values.size()) return nullptr;
    ListNode* node = new ListNode(values[index]);
    node->next = createListRecursive(values, index + 1);
    return node;
}

// Method 3: Using dummy node
ListNode* createListWithDummy(vector<int>& values) {
    ListNode* dummy = new ListNode(0);
    ListNode* cur = dummy;
    
    for (int val : values) {
        cur->next = new ListNode(val);
        cur = cur->next;
    }
    
    return dummy->next;
}

// Method 4: Create list from array
ListNode* createListFromArray(int arr[], int n) {
    if (n == 0) return nullptr;
    
    ListNode* head = new ListNode(arr[0]);
    ListNode* cur = head;
    
    for (int i = 1; i < n; ++i) {
        cur->next = new ListNode(arr[i]);
        cur = cur->next;
    }
    
    return head;
}

Utility Functions

// Print linked list (for debugging)
void printList(ListNode* head) {
    ListNode* cur = head;
    while (cur != nullptr) {
        cout << cur->val;
        if (cur->next != nullptr) cout << " -> ";
        cur = cur->next;
    }
    cout << endl;
}

// Get length of linked list
int getLength(ListNode* head) {
    int length = 0;
    ListNode* cur = head;
    while (cur != nullptr) {
        length++;
        cur = cur->next;
    }
    return length;
}

// Convert linked list to vector
vector<int> listToVector(ListNode* head) {
    vector<int> result;
    ListNode* cur = head;
    while (cur != nullptr) {
        result.push_back(cur->val);
        cur = cur->next;
    }
    return result;
}

// Delete entire linked list (free memory)
void deleteList(ListNode* head) {
    while (head != nullptr) {
        ListNode* temp = head;
        head = head->next;
        delete temp;
    }
}

Example Usage

// Example: Create list [1, 2, 3, 4, 5]
vector<int> values = {1, 2, 3, 4, 5};
ListNode* head = createList(values);

// Print the list
printList(head);  // Output: 1 -> 2 -> 3 -> 4 -> 5

// Get length
int len = getLength(head);  // len = 5

// Convert to vector
vector<int> vec = listToVector(head);  // vec = [1, 2, 3, 4, 5]

// Clean up
deleteList(head);

Basic Operations

When to use: You need to “visit every node”, “count nodes”, “find a value”, or “collect values into an array”. Also the foundation for insert/delete at arbitrary positions.

Traversal

// Iterative traversal
void traverse(ListNode* head) {
    ListNode* cur = head;
    while (cur != nullptr) {
        // Process cur->val
        cur = cur->next;
    }
}

// Recursive traversal
void traverseRecursive(ListNode* head) {
    if (head == nullptr) return;
    // Process head->val
    traverseRecursive(head->next);
}

Insertion

// Insert at head
ListNode* insertAtHead(ListNode* head, int val) {
    ListNode* newNode = new ListNode(val);
    newNode->next = head;
    return newNode;
}

// Insert after node
void insertAfter(ListNode* node, int val) {
    ListNode* newNode = new ListNode(val);
    newNode->next = node->next;
    node->next = newNode;
}

Deletion

// Delete node (given node to delete, not head)
void deleteNode(ListNode* node) {
    node->val = node->next->val;
    node->next = node->next->next;
}

// Delete node with value
ListNode* deleteNode(ListNode* head, int val) {
    if (head == nullptr) return nullptr;
    if (head->val == val) return head->next;
    
    ListNode* cur = head;
    while (cur->next != nullptr) {
        if (cur->next->val == val) {
            cur->next = cur->next->next;
            break;
        }
        cur = cur->next;
    }
    return head;
}
ID Title Link Solution
203 Remove Linked List Elements Link Solution
237 Delete Node in a Linked List Link -

Two Pointers

When to use: The problem says “middle of list”, “kth from end”, “intersection of two lists”, or “split list into halves”. Use fast/slow pointers to solve in one pass without knowing the length.

Fast and Slow Pointers

slow moves 1 step · fast moves 2 steps Initial slow fast 1 2 3 4 5 Step 1 slow fast 1 2 3 4 5 Step 2 slow fast 1 2 3 middle 4 5
// Find middle node
ListNode* findMiddle(ListNode* head) {
    ListNode* slow = head;
    ListNode* fast = head;
    while (fast != nullptr && fast->next != nullptr) {
        slow = slow->next;
        fast = fast->next->next;
    }
    return slow;
}

// Find kth node from end
ListNode* findKthFromEnd(ListNode* head, int k) {
    ListNode* fast = head;
    for (int i = 0; i < k; ++i) {
        if (fast == nullptr) return nullptr;
        fast = fast->next;
    }
    ListNode* slow = head;
    while (fast != nullptr) {
        slow = slow->next;
        fast = fast->next;
    }
    return slow;
}

Two Pointers for Partitioning

// Partition list around value x
ListNode* partition(ListNode* head, int x) {
    ListNode* less = new ListNode(0);
    ListNode* greater = new ListNode(0);
    ListNode* lessCur = less;
    ListNode* greaterCur = greater;
    
    while (head != nullptr) {
        if (head->val < x) {
            lessCur->next = head;
            lessCur = lessCur->next;
        } else {
            greaterCur->next = head;
            greaterCur = greaterCur->next;
        }
        head = head->next;
    }
    
    greaterCur->next = nullptr;
    lessCur->next = greater->next;
    return less->next;
}
ID Title Link Solution
876 Middle of the Linked List Link Solution
19 Remove Nth Node From End of List Link -

Dummy Node Pattern

When to use: The problem involves “delete head”, “merge lists”, “insert at front”, or any operation where the head might change. A dummy node in front of head eliminates null-check edge cases.

// Remove elements with dummy node
ListNode* removeElements(ListNode* head, int val) {
    ListNode* dummy = new ListNode(0);
    dummy->next = head;
    ListNode* cur = dummy;
    
    while (cur->next != nullptr) {
        if (cur->next->val == val) {
            cur->next = cur->next->next;
        } else {
            cur = cur->next;
        }
    }
    
    return dummy->next;
}

Key Benefits:

  • Handles empty list case
  • Simplifies head deletion
  • Reduces special case handling
ID Title Link Solution
203 Remove Linked List Elements Link Solution

Reversal

When to use: The problem says “reverse linked list”, “reverse between positions”, “reverse in groups of k”, or “palindrome linked list”. The core trick is rewiring next pointers as you walk.

Reverse Entire List

Step 1 prev curr next null 1 2 3 4 Step 2 prev curr next null 1 2 3 4 Step 3 prev curr next null 1 2 3 4 ← reversed → original
// Iterative reversal
ListNode* reverseList(ListNode* head) {
    ListNode* prev = nullptr;
    ListNode* cur = head;
    while (cur != nullptr) {
        ListNode* next = cur->next;
        cur->next = prev;
        prev = cur;
        cur = next;
    }
    return prev;
}

// Recursive reversal
ListNode* reverseListRecursive(ListNode* head) {
    if (head == nullptr || head->next == nullptr) return head;
    ListNode* newHead = reverseListRecursive(head->next);
    head->next->next = head;
    head->next = nullptr;
    return newHead;
}

Reverse Between Positions

// Reverse nodes from position left to right
ListNode* reverseBetween(ListNode* head, int left, int right) {
    ListNode* dummy = new ListNode(0);
    dummy->next = head;
    ListNode* prev = dummy;
    
    // Move to left position
    for (int i = 1; i < left; ++i) {
        prev = prev->next;
    }
    
    // Reverse
    ListNode* cur = prev->next;
    for (int i = 0; i < right - left; ++i) {
        ListNode* next = cur->next;
        cur->next = next->next;
        next->next = prev->next;
        prev->next = next;
    }
    
    return dummy->next;
}

Reverse in Groups

// Reverse nodes in k-group
ListNode* reverseKGroup(ListNode* head, int k) {
    ListNode* cur = head;
    int count = 0;
    while (cur != nullptr && count < k) {
        cur = cur->next;
        count++;
    }
    
    if (count == k) {
        cur = reverseKGroup(cur, k);
        while (count-- > 0) {
            ListNode* next = head->next;
            head->next = cur;
            cur = head;
            head = next;
        }
        head = cur;
    }
    return head;
}
ID Title Link Solution
206 Reverse Linked List Link Solution
92 Reverse Linked List II Link Solution
25 Reverse Nodes in k-Group Link Solution
24 Swap Nodes in Pairs Link Solution

Merge

When to use: The problem says “merge two sorted lists”, “merge k sorted lists”, or “add two numbers represented as lists”. Compare heads, advance the smaller, and use a dummy node to collect the result.

Merge Two Sorted Lists

list1 1 3 5 list2 2 4 6 result 1 2 3 4 5 6 from list1 from list2
// Merge two sorted lists
ListNode* mergeTwoLists(ListNode* list1, ListNode* list2) {
    ListNode* dummy = new ListNode(0);
    ListNode* cur = dummy;
    
    while (list1 != nullptr && list2 != nullptr) {
        if (list1->val <= list2->val) {
            cur->next = list1;
            list1 = list1->next;
        } else {
            cur->next = list2;
            list2 = list2->next;
        }
        cur = cur->next;
    }
    
    cur->next = (list1 != nullptr) ? list1 : list2;
    return dummy->next;
}

Merge K Sorted Lists

// Merge k sorted lists using divide and conquer
ListNode* mergeKLists(vector<ListNode*>& lists) {
    if (lists.empty()) return nullptr;
    return mergeKListsHelper(lists, 0, lists.size() - 1);
}

ListNode* mergeKListsHelper(vector<ListNode*>& lists, int left, int right) {
    if (left == right) return lists[left];
    int mid = left + (right - left) / 2;
    ListNode* leftList = mergeKListsHelper(lists, left, mid);
    ListNode* rightList = mergeKListsHelper(lists, mid + 1, right);
    return mergeTwoLists(leftList, rightList);
}
ID Title Link Solution
21 Merge Two Sorted Lists Link -
23 Merge k Sorted Lists Link Solution
2 Add Two Numbers Link Solution
1669 Merge In Between Linked Lists Link Solution

Cycle Detection

When to use: The problem asks “has cycle”, “find cycle start”, or “find the duplicate number” (which reduces to cycle detection). Floyd’s algorithm: if fast and slow meet, there’s a cycle.

Detect Cycle (Floyd’s Algorithm)

Phase 1 — fast and slow meet 1 2 3 cycle start 4 5 cycle slow fast meet here! Phase 2 — reset slow to head, both advance ×1 1 2 3 4 5 slow (reset) fast ↑ cycle start — both meet here
// Detect cycle using Floyd's cycle detection
bool hasCycle(ListNode* head) {
    if (head == nullptr || head->next == nullptr) return false;
    
    ListNode* slow = head;
    ListNode* fast = head;
    
    while (fast != nullptr && fast->next != nullptr) {
        slow = slow->next;
        fast = fast->next->next;
        if (slow == fast) return true;
    }
    
    return false;
}

// Find cycle start node
ListNode* detectCycle(ListNode* head) {
    ListNode* slow = head;
    ListNode* fast = head;
    
    // Find meeting point
    while (fast != nullptr && fast->next != nullptr) {
        slow = slow->next;
        fast = fast->next->next;
        if (slow == fast) break;
    }
    
    if (fast == nullptr || fast->next == nullptr) return nullptr;
    
    // Find cycle start
    slow = head;
    while (slow != fast) {
        slow = slow->next;
        fast = fast->next;
    }
    
    return slow;
}
ID Title Link Solution
141 Linked List Cycle Link -
142 Linked List Cycle II Link -

Circular Linked List

When to use: The problem mentions “circular linked list”, “sorted circular list”, or “rotate list”. The key difference from normal lists: the tail’s next points back to the head instead of nullptr.

Insert into Sorted Circular List

// Insert into sorted circular linked list
ListNode* insert(ListNode* head, int insertVal) {
    if (head == nullptr) {
        ListNode* newNode = new ListNode(insertVal);
        newNode->next = newNode;
        return newNode;
    }
    
    ListNode* prev = head;
    ListNode* cur = head->next;
    
    while (cur != head) {
        // Normal insertion point
        if (prev->val <= insertVal && insertVal <= cur->val) {
            break;
        }
        // At the boundary (largest to smallest)
        if (prev->val > cur->val && (insertVal >= prev->val || insertVal <= cur->val)) {
            break;
        }
        prev = cur;
        cur = cur->next;
    }
    
    prev->next = new ListNode(insertVal);
    prev->next->next = cur;
    return head;
}
ID Title Link Solution
708 Insert into a Sorted Circular Linked List Link Solution
382 Linked List Random Node Link Solution

Quick-Reference Summary

Pattern Signal Phrases Key Idea
Two Pointers “middle”, “kth from end”, “intersection” Fast moves 2x, slow moves 1x
Dummy Node “delete head”, “merge”, “insert at front” Avoids null-check edge cases
Reversal “reverse list”, “reverse between” Rewire next pointers
Merge “merge sorted”, “merge k lists” Compare heads, advance smaller
Cycle Detection “has cycle”, “cycle start” Floyd’s: fast meets slow = cycle

More templates