Merge Two Sorted Lists
Splice together nodes of two sorted linked lists into a single sorted list. The canonical problem for learning pointer reassignment and the dummy head technique.
Problem Statement
You are given the heads of two sorted linked lists list1 and list2.
Merge the two lists into one sorted list. The list should be made by splicing together the nodes of the first two lists.
Return the head of the merged linked list.
Examples & Constraints
- The number of nodes in both lists is in the range [0, 50].
- -100 <= Node.val <= 100
- Both list1 and list2 are sorted in non-decreasing order.
Iterative Splicing with Dummy Head
Optimal ApproachUse a dummy head node and a current pointer to stitch existing nodes together in O(1) auxiliary space without allocating new nodes.
Every node across both input lists of lengths N and M is visited and linked exactly once.
No new nodes are created. Only a single dummy node and pointer references are used.
Underlying algorithmic logic
The Dummy Head Technique: Eliminating Edge Cases
In linked list manipulation, the most common source of null pointer exceptions is deciding which node becomes the head of the merged list.
By initializing a sentinel dummy node (dummy) and a tracking pointer (tail = dummy):
- We never have to write special branches for the first node insertion.
- While both
list1andlist2are non-null:
- If
list1.val <= list2.val, wiretail.next = list1and advancelist1 = list1.next. - Else, wire
tail.next = list2and advancelist2 = list2.next. - Advance
tail = tail.next.
- When one list runs out of nodes, attach the remaining tail directly:
tail.next = (list1 != null) ? list1 : list2. - Return
dummy.nextas the true head of the merged list.
In-Place Pointer Rewiring
Notice that we do not allocate any new list nodes! We only change the next pointers of the existing input nodes. This guarantees O(1) auxiliary memory.
Step-by-step execution walkthrough
Create dummy node (-1). tail points to dummy. list1 at 1, list2 at 1.
list1.val (1) <= list2.val (1). tail.next points to list1 (1). Advance list1.
list2.val (1) < list1.val (2). tail.next points to list2 (1). Advance list2.
Continue splicing until list1 is exhausted. Wire remaining list2 directly.
- •Optimal O(1) auxiliary space
- •Clean logic without edge cases thanks to dummy head
- •Mutates original list nodes (standard competitive programming behavior)
Code Implementations
Ready-to-useCopy & paste production-ready solutions for Iterative Splicing with Dummy Head in your language of choice
class ListNode:def __init__(self, val=0, next=None):self.val = valself.next = nextdef merge_two_lists(list1: ListNode | None, list2: ListNode | None) -> ListNode | None:dummy = ListNode(-1)tail = dummywhile list1 and list2:if list1.val <= list2.val:tail.next = list1list1 = list1.nextelse:tail.next = list2list2 = list2.nexttail = tail.nexttail.next = list1 if list1 else list2return dummy.nextdef to_list(head: ListNode | None) -> list[int]:res = []curr = headwhile curr:res.append(curr.val)curr = curr.nextreturn resif __name__ == "__main__":l1 = ListNode(1, ListNode(2, ListNode(4)))l2 = ListNode(1, ListNode(3, ListNode(4)))merged = merge_two_lists(l1, l2)print("Merged list:", to_list(merged))
Understand Singly Linked List Visually
Interact with linear chain node arrays, traversal, head/tail adjustments, and index operations. Test live edge cases and watch memory state transitions step-by-step.
Frequently Asked Questions
Related Logic & Algorithm Problems
Reverse Linked List
Reverse the directional arrows of a singly linked list in-place. The classic test of reference manipulation and memory pointer management.
Two Sum
Find the two numbers in an array that sum up to a target value. The quintessential problem for learning how to trade memory for speed using a Hash Map.
Linked List Cycle
Determine if a linked list contains a cycle using Floyd's Tortoise and Hare algorithm. The foundational problem for understanding two-speed pointer convergence in finite loops.