Skip to content

Merge Two Sorted Lists

You are given the heads of two sorted linked lists list1 and list2. Merge the two lists in a single sorted list. The list should be made by splicing together the nodes of the two lists.

Return the head of the merged linked list.

list1list2OutputExplanation
[1, 2, 4][1, 3, 4][1, 1, 2, 3, 4, 4]All six nodes merged in sorted order
[][][]Both lists are empty
[][0][0]First list is empty, return second list
  • 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.
ApproachTimeSpaceNodes CreatedBest When
IterativeO(m + n)O(1)Zero (reuse input nodes)General case — clearer, no stack overhead
RecursiveO(m + n)O(m + n)Zero (reuse input nodes)Learning recursion, practicing pointer manipulation

* Space refers to extra memory excluding the output list. Both approaches reuse nodes from the input lists.

  • Pick Iterative if you want the most efficient solution with minimal memory overhead.
  • Pick Recursive if you are practicing recursion or want to understand the elegant elegance of self-similar problems.
Recommended
Iterative
O(m + n) time · O(1) space
Elegant
Recursive
O(m + n) time · O(m + n) space
★ Recommended

Maintain a pointer to the tail of the merged list and step through both input lists, always appending the smaller node to the result.

The key idea is simple: maintain a tail pointer that points to the last node of the merged list. Compare the next nodes from both lists, append the smaller one, and advance its pointer. When one list is exhausted, append the entire remainder of the other list.

⏱ Time O(m + n) Single pass through both lists 💾 Space O(1) Only pointer variables

Input: list1 = [1, 2, 4], list2 = [1, 3, 4]

Stepcurrent.nextlist1list2list1.val vs list2.valAction
1dummy111 == 1 → choose list1Attach list1 node (1), advance list1
21212 > 1 → choose list2Attach list2 node (1), advance list2
31232 < 3 → choose list1Attach list1 node (2), advance list1
42434 > 3 → choose list2Attach list2 node (3), advance list2
53444 == 4 → choose list1Attach list1 node (4), advance list1
64null4list1 exhaustedAttach entire list2 (4)

Final Output: 1 → 1 → 2 → 3 → 4 → 4

Animated walkthrough

How the iterative solution merges two sorted lists

Watch the tail pointer move through both input lists, always choosing the smaller node at each step.

Step 1 of 7 Target: merged
Waiting to begin...
Array state
Memory / lookup state

function mergeTwoSortedListsIterative(list1, list2):
dummy = new ListNode(0)
current = dummy
while list1 and list2:
if list1.val <= list2.val:
current.next = list1
list1 = list1.next
else:
current.next = list2
list2 = list2.next
current = current.next
// Append remaining nodes
if list1:
current.next = list1
else:
current.next = list2
return dummy.next
merge_two_sorted_lists_iterative.py
from typing import Optional
class ListNode:
def __init__(self, val=0, next=None):
self.val = val
self.next = next
def merge_two_sorted_lists_iterative(
list1: Optional[ListNode], list2: Optional[ListNode]
) -> Optional[ListNode]:
"""
Merge two sorted linked lists iteratively.
Time Complexity: O(m + n) where m and n are the lengths of list1 and list2
Space Complexity: O(1) excluding the output list
"""
# Create a dummy node to simplify the code
dummy = ListNode(0)
current = dummy
# Traverse both lists and append the smaller node
while list1 and list2:
if list1.val <= list2.val:
current.next = list1
list1 = list1.next
else:
current.next = list2
list2 = list2.next
current = current.next
# Append the remaining nodes
if list1:
current.next = list1
else:
current.next = list2
return dummy.next
# Helper function to create a linked list from a list
def create_linked_list(values):
if not values:
return None
head = ListNode(values[0])
current = head
for val in values[1:]:
current.next = ListNode(val)
current = current.next
return head
# Helper function to convert linked list to list for easy testing
def linked_list_to_list(node):
result = []
while node:
result.append(node.val)
node = node.next
return result
# Test cases
list1 = create_linked_list([1, 2, 4])
list2 = create_linked_list([1, 3, 4])
result = merge_two_sorted_lists_iterative(list1, list2)
print(linked_list_to_list(result)) # [1, 1, 2, 3, 4, 4]
list1 = create_linked_list([])
list2 = create_linked_list([])
result = merge_two_sorted_lists_iterative(list1, list2)
print(linked_list_to_list(result)) # []
list1 = create_linked_list([])
list2 = create_linked_list([0])
result = merge_two_sorted_lists_iterative(list1, list2)
print(linked_list_to_list(result)) # [0]
🎯 Interview Favourite

At each step, decide which of the two next nodes (from list1 or list2) should come first, set it to point to the merged result of the remaining lists, and return it.

This approach is elegant because the problem exhibits optimal substructure: merging two lists is the same as choosing the smaller head and then merging the remainder. The recursion naturally mirrors the structure of linked lists.

⏱ Time O(m + n) Single pass through both lists 💾 Space O(m + n) Call stack depth

Input: list1 = [1, 2, 4], list2 = [1, 3, 4]

The recursion tree shows how the problem breaks down:

merge([1, 2, 4], [1, 3, 4])
├─ 1 <= 1 → return 1.next = merge([2, 4], [1, 3, 4])
│ ├─ 2 > 1 → return 1.next = merge([2, 4], [3, 4])
│ │ ├─ 2 < 3 → return 2.next = merge([4], [3, 4])
│ │ │ ├─ 4 > 3 → return 3.next = merge([4], [4])
│ │ │ │ ├─ 4 <= 4 → return 4.next = merge(null, [4])
│ │ │ │ │ └─ return 4
│ │ │ │ └─ result: 4 → 4
│ │ │ └─ result: 3 → 4 → 4
│ │ └─ result: 2 → 3 → 4 → 4
│ └─ result: 1 → 2 → 3 → 4 → 4
└─ result: 1 → 1 → 2 → 3 → 4 → 4
function mergeTwoSortedListsRecursive(list1, list2):
// Base cases
if list1 is null:
return list2
if list2 is null:
return list1
// Recursive case: choose the smaller head and recurse
if list1.val <= list2.val:
list1.next = mergeTwoSortedListsRecursive(list1.next, list2)
return list1
else:
list2.next = mergeTwoSortedListsRecursive(list1, list2.next)
return list2
merge_two_sorted_lists_recursive.py
from typing import Optional
class ListNode:
def __init__(self, val=0, next=None):
self.val = val
self.next = next
def merge_two_sorted_lists_recursive(
list1: Optional[ListNode], list2: Optional[ListNode]
) -> Optional[ListNode]:
"""
Merge two sorted linked lists recursively.
Time Complexity: O(m + n) where m and n are the lengths of list1 and list2
Space Complexity: O(m + n) due to the recursion call stack
"""
# Base cases: if one list is empty, return the other
if not list1:
return list2
if not list2:
return list1
# Compare the values and recursively merge
if list1.val <= list2.val:
list1.next = merge_two_sorted_lists_recursive(list1.next, list2)
return list1
else:
list2.next = merge_two_sorted_lists_recursive(list1, list2.next)
return list2
# Helper function to create a linked list from a list
def create_linked_list(values):
if not values:
return None
head = ListNode(values[0])
current = head
for val in values[1:]:
current.next = ListNode(val)
current = current.next
return head
# Helper function to convert linked list to list for easy testing
def linked_list_to_list(node):
result = []
while node:
result.append(node.val)
node = node.next
return result
# Test cases
list1 = create_linked_list([1, 2, 4])
list2 = create_linked_list([1, 3, 4])
result = merge_two_sorted_lists_recursive(list1, list2)
print(linked_list_to_list(result)) # [1, 1, 2, 3, 4, 4]
list1 = create_linked_list([])
list2 = create_linked_list([])
result = merge_two_sorted_lists_recursive(list1, list2)
print(linked_list_to_list(result)) # []
list1 = create_linked_list([])
list2 = create_linked_list([0])
result = merge_two_sorted_lists_recursive(list1, list2)
print(linked_list_to_list(result)) # [0]
CaseBehaviorExample
Both lists emptyReturn null[] + [][]
First list emptyReturn second list[] + [1, 2][1, 2]
Second list emptyReturn first list[1, 2] + [][1, 2]
Single-node listsMerge correctly[1] + [2][1, 2]
Duplicate valuesMerge in stable order[1, 3] + [1, 3][1, 1, 3, 3]
Negative valuesTreat as regular integers[-2, 0, 2] + [-1, 1][-2, -1, 0, 1, 2]
✓ Simple

A third approach demonstrating an alternative technique for solving this problem. This implementation optimizes either time or space complexity compared to the previous approaches.

⏱ Time O(n) Optimized complexity 💾 Space O(1) Efficient space usage
function approach3():
// Implementation approach goes here
merge_two_sorted_lists_space_optimized.py
"""
Solution for Merge Two Sorted Lists
"""
def solve():
"""Implementation for approach 3 of Merge Two Sorted Lists"""
pass
if __name__ == "__main__":
print("Solution ready")