Code Templates
Master linked list manipulation with these standardized code templates. Each template provides implementations in JavaScript, Python, Java, C++, Go, and Ruby with detailed explanations of pointer techniques. Refer back to the Concept Guide for the theoretical foundation.
Main Template: Reverse a Linked List
This is the fundamental template for reversing a linked list, which is used in many problems including palindrome checking and list reordering. This template directly applies to the Reverse Linked List problem.
Template Implementation
function reverseList(head) {
let prev = null;
let current = head;
while (current !== null) {
const next = current.next; // Save next node
current.next = prev; // Reverse pointer
prev = current; // Move prev forward
current = next; // Move current forward
}
return prev; // New head
}def reverse_list(head):
prev = None
current = head
while current is not None:
next_node = current.next # Save next node
current.next = prev # Reverse pointer
prev = current # Move prev forward
current = next_node # Move current forward
return prev # New headpublic ListNode reverseList(ListNode head) {
ListNode prev = null;
ListNode current = head;
while (current != null) {
ListNode next = current.next; // Save next node
current.next = prev; // Reverse pointer
prev = current; // Move prev forward
current = next; // Move current forward
}
return prev; // New head
}ListNode* reverseList(ListNode* head) {
ListNode* prev = nullptr;
ListNode* current = head;
while (current != nullptr) {
ListNode* next = current->next; // Save next node
current->next = prev; // Reverse pointer
prev = current; // Move prev forward
current = next; // Move current forward
}
return prev; // New head
}func reverseList(head *ListNode) *ListNode {
var prev *ListNode
current := head
for current != nil {
next := current.Next // Save next node
current.Next = prev // Reverse pointer
prev = current // Move prev forward
current = next // Move current forward
}
return prev // New head
}def reverse_list(head)
prev = nil
current = head
while current
next_node = current.next # Save next node
current.next = prev # Reverse pointer
prev = current # Move prev forward
current = next_node # Move current forward
end
prev # New head
endCode Breakdown
Key Variables:
prev: Tracks the previously processed node. Initially null because the first node will point to nothing when reversed.current: The node currently being processed. Starts at the head and moves forward.next: A temporary variable to save the next node before we overwritecurrent.next.
Algorithm Visualization:
stateDiagram-v2
[*] --> Start
Start --> Check: current != null
Check --> Save: Save current.next
Save --> Reverse: current.next = prev
Reverse --> MovePrev: prev = current
MovePrev --> MoveCurrent: current = next
MoveCurrent --> Check
Check --> End: current == null
End --> [*]: return prev
note right of Save
Must save before
overwriting!
end note
note right of Reverse
This is the core
pointer reversal
end note
Critical Sections:
Initialization:
prev = null,current = head. The first node after reversal will be the last node, so itsnextshould point to null.Saving Next: Before modifying
current.next, we MUST save it tonext. If we don’t, we lose the reference to the rest of the list.Reversing Pointer:
current.next = prevchanges the pointer direction from forward to backward.Moving Pointers: Move both pointers forward.
prevtakes the place ofcurrent, andcurrenttakes the place of the savednext.
Variations
Two Pointer: Find Middle Node
Useful for problems like Palindrome Linked List.
function findMiddle(head) {
let slow = head;
let fast = head;
while (fast !== null && fast.next !== null) {
slow = slow.next; // Move 1 step
fast = fast.next.next; // Move 2 steps
}
return slow; // Middle node
}def find_middle(head):
slow = fast = head
while fast and fast.next:
slow = slow.next # Move 1 step
fast = fast.next.next # Move 2 steps
return slow # Middle nodepublic ListNode findMiddle(ListNode head) {
ListNode slow = head;
ListNode fast = head;
while (fast != null && fast.next != null) {
slow = slow.next;
fast = fast.next.next;
}
return slow; // 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; // Middle node
}func findMiddle(head *ListNode) *ListNode {
slow, fast := head, head
for fast != nil && fast.Next != nil {
slow = slow.Next // Move 1 step
fast = fast.Next.Next // Move 2 steps
}
return slow // Middle node
}def find_middle(head)
slow = fast = head
while fast && fast.next
slow = slow.next # Move 1 step
fast = fast.next.next # Move 2 steps
end
slow # Middle node
endCycle Detection: Floyd’s Algorithm
Detect if a cycle exists in a linked list. Directly applies to Linked List Cycle.
function hasCycle(head) {
let slow = head;
let fast = head;
while (fast !== null && fast.next !== null) {
slow = slow.next;
fast = fast.next.next;
if (slow === fast) return true;
}
return false;
}def has_cycle(head):
slow = fast = head
while fast and fast.next:
slow = slow.next
fast = fast.next.next
if slow == fast:
return True
return Falsepublic boolean hasCycle(ListNode head) {
ListNode slow = head;
ListNode fast = head;
while (fast != null && fast.next != null) {
slow = slow.next;
fast = fast.next.next;
if (slow == fast) return true;
}
return false;
}bool hasCycle(ListNode* head) {
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;
}func hasCycle(head *ListNode) bool {
slow, fast := head, head
for fast != nil && fast.Next != nil {
slow = slow.Next
fast = fast.Next.Next
if slow == fast {
return true
}
}
return false
}def has_cycle(head)
slow = fast = head
while fast && fast.next
slow = slow.next
fast = fast.next.next
return true if slow == fast
end
false
endMerge Two Sorted Lists
Merge two sorted lists into one sorted list. Directly applies to Merge Two Sorted Lists.
function mergeTwoLists(list1, list2) {
const dummy = new ListNode(0);
let tail = dummy;
while (list1 !== null && list2 !== null) {
if (list1.val < list2.val) {
tail.next = list1;
list1 = list1.next;
} else {
tail.next = list2;
list2 = list2.next;
}
tail = tail.next;
}
// Append remaining nodes
tail.next = list1 !== null ? list1 : list2;
return dummy.next;
}def merge_two_lists(list1, list2):
dummy = ListNode(0)
tail = dummy
while list1 and list2:
if list1.val < list2.val:
tail.next = list1
list1 = list1.next
else:
tail.next = list2
list2 = list2.next
tail = tail.next
# Append remaining nodes
tail.next = list1 or list2
return dummy.nextpublic ListNode mergeTwoLists(ListNode list1, ListNode list2) {
ListNode dummy = new ListNode(0);
ListNode tail = dummy;
while (list1 != null && list2 != null) {
if (list1.val < list2.val) {
tail.next = list1;
list1 = list1.next;
} else {
tail.next = list2;
list2 = list2.next;
}
tail = tail.next;
}
// Append remaining nodes
tail.next = list1 != null ? list1 : list2;
return dummy.next;
}ListNode* mergeTwoLists(ListNode* list1, ListNode* list2) {
ListNode* dummy = new ListNode(0);
ListNode* tail = dummy;
while (list1 != nullptr && list2 != nullptr) {
if (list1->val < list2->val) {
tail->next = list1;
list1 = list1->next;
} else {
tail->next = list2;
list2 = list2->next;
}
tail = tail->next;
}
// Append remaining nodes
tail->next = list1 != nullptr ? list1 : list2;
return dummy->next;
}func mergeTwoLists(list1 *ListNode, list2 *ListNode) *ListNode {
dummy := &ListNode{}
tail := dummy
for list1 != nil && list2 != nil {
if list1.Val < list2.Val {
tail.Next = list1
list1 = list1.Next
} else {
tail.Next = list2
list2 = list2.Next
}
tail = tail.Next
}
// Append remaining nodes
if list1 != nil {
tail.Next = list1
} else {
tail.Next = list2
}
return dummy.Next
}def merge_two_lists(list1, list2)
dummy = ListNode.new(0)
tail = dummy
while list1 && list2
if list1.val < list2.val
tail.next = list1
list1 = list1.next
else
tail.next = list2
list2 = list2.next
end
tail = tail.next
end
# Append remaining nodes
tail.next = list1 || list2
dummy.next
endPractice
Ready to apply these templates? Visit our Practice Problems to solve real interview questions using these patterns.