Easy

Merge Two Sorted Lists

Weave the two lists together, always taking the smaller head.

Approach

Use a dummy head to simplify edge cases. Repeatedly attach the smaller of the two current nodes and advance that list. When one list runs out, link the remainder of the other. The dummy's next is the merged head.

Time complexity

O(n + m)

Space complexity

O(1)

Common mistake

Not using a dummy node, which forces awkward special-casing of the first element.

Interactive walkthrough — step through it below, free and without an account

Problem

Given the heads of two singly linked lists whose values are already sorted in nondecreasing order, combine them into one sorted linked list. Reuse the existing nodes rather than creating a separate collection, and return the head of the combined list.

Examples

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

Output: [1,1,2,3,4,4]

Repeatedly choose the smaller head: 1 from list1, 1 from list2, 2, 3, and then the remaining 4s.

Input: list1 = [], list2 = [0]

Output: [0]

When one list is empty, the other list is already the complete answer.

Problem

Problem

Given the heads of two singly linked lists whose values are already sorted in nondecreasing order, combine them into one sorted linked list. Reuse the existing nodes rather than creating a separate collection, and return the head of the combined list.

Problem and Goal

Learning goal: Recognize the merge operation as a controlled weave of two already sorted linked lists.

Core idea Each list exposes a current head node. Because both lists are sorted, the smallest node not yet used must be one of those two heads. Choose the smaller head, append it to the result, and advance only the list that supplied it. This avoids scanning values that cannot be the next answer.

Algorithm plan

  • Keep pointers a and b at the current nodes of the two lists.
  • Compare a.val and b.val while both pointers are non-null.
  • Attach the smaller node to the result and advance its source pointer.
  • Attach whichever remainder is still non-null.

Micro-example For [1,2,4] and [1,3,4], the first comparison is 1 <= 1. Take the first list's node, then compare 2 with 1.

Pitfalls

  • Treating the lists as unsorted can lead to unnecessary work.
  • Advancing both pointers after one choice skips a node.
  • Forgetting the remainder loses the tail of one list.

Recap

  • The next answer is always the smaller visible head.
  • Only one input pointer advances per merge step.
  • The operation can reuse existing nodes.

Problem and Goal

Choose the smaller head

At every moment, the next node in sorted order is the smaller of the two current heads.

Compare only two nodes, attach one, and advance exactly one list.

Why the Dummy Head Matters

Learning goal: Understand how a dummy node removes special cases when building the merged list.

Core idea A result list normally needs special handling for its first node because there is no previous node to update. Create a temporary dummy node first, then always attach the chosen node after tail. The first real node becomes dummy.next, whether it came from the first list, the second list, or the only non-empty list.

Data structure model

  • dummy: a fixed sentinel before the real answer.
  • tail: the last node currently in the merged chain.
  • a, b: the unmerged suffixes of the two inputs.
  • After attaching a node, set tail = tail.next.

Uniform pointer update

With a dummy, every insertion is simply tail.next = chosen; no first-node branch is needed.

Micro-example Initially, dummy -> None and tail = dummy. If list1 contributes 1, the update is dummy.next = 1, then tail moves to that 1.

Pitfalls

  • Returning dummy includes the sentinel in the answer.
  • Reusing tail as an input pointer can disconnect the result.
  • Creating new nodes is unnecessary for this problem.

Recap

  • The dummy is scaffolding, not part of the returned list.
  • dummy.next is the merged head.
  • One invariant makes every append identical.

Why the Dummy Head Matters

`dummy` sits before every real result node, including the first one.

dummy -> 1

Main Algorithm

Learning goal: Translate the merge invariant into a short, constant-space procedure.

Core idea The merged prefix is always sorted, and tail points to its final node. While both inputs remain, the smaller current value is safe to append because every other unmerged node is at least as large as its own current head. Once either pointer becomes null, the other pointer already names a sorted remainder, so link it directly.

Algorithm plan

Code
Create dummy and set tail = dummy
Set a and b to the two list heads
While a and b are not null:
    choose a if a.val <= b.val; otherwise choose b
    attach chosen after tail
    move tail to chosen
    advance the chosen input pointer
Attach a if it remains; otherwise attach b
Return dummy.next

Why linking the remainder works

The untouched suffix is already sorted, and every node in it is no smaller than the merged prefix's last node.

Micro-example After producing 1,1,2,3,4, list1 is empty and list2 points to its final 4. One link completes the answer.

Pitfalls

  • Use <= consistently if equal nodes should favor the first list.
  • Save or identify the chosen node before advancing its input pointer.
  • Check both pointers before reading .val.

Recap

  • Compare, attach, advance: one repeated operation.
  • Link the remaining suffix in one step.
  • The returned chain begins at dummy.next.

Main Algorithm

ApproachTimeExtra spaceKey trade-off
Dummy + two pointersO(n + m)O(1)Uniform pointer logic
Copy values, sort, rebuildO((n + m) log(n + m))O(n + m)Ignores existing order
Repeatedly scan both listsO(nm)O(1)Repeats comparisons

End-to-End Walkthrough

Learning goal: Trace every pointer and link while merging one concrete pair of lists.

Core idea Use list1 = [1,2,4] and list2 = [1,3,4]. The visualization treats each value as an existing node and shows the next map changing as links are woven together. Equal values are resolved by taking list1 first, using the <= rule.

Pointer movement

StepComparisonChosen nodePointer advanced
11 <= 1list1 1a
22 > 1list2 1b
32 <= 3list1 2a
44 > 3list2 3b
54 <= 4list1 4a
6remainderlist2 4b

Micro-example The links evolve as dummy -> 1 -> 1 -> 2 -> 3 -> 4 -> 4. The final result is [1,1,2,3,4,4].

Pitfalls

  • A comparison event should attach only one node.
  • The old next links are rewired through tail; do not duplicate nodes.
  • The final remainder step is part of the algorithm, not an optional cleanup.

Recap

  • Follow the smaller head at each comparison.
  • The merged prefix remains sorted after every attachment.
  • The visualization ends at dummy.next.

End-to-End Walkthrough

Step through merging [1,2,4] and [1,3,4] by rewiring existing nodes.

Linked list
1 / 8
Start with a dummy node and compare 1 with 1.
head →dummy
prev
dummy
next ∅
·
curr
1
 
2
 
4
next ∅
·
1
 
3
 
4
next ∅

Action: init

The dummy makes the first attachment ordinary.The merged prefix is sorted and ends at prev.
1 / 8

Pitfalls and Edge Cases

Learning goal: Identify the pointer mistakes that most often break linked-list merging.

Core idea The algorithm is short, but linked-list code fails when it mishandles the first node, null pointers, or the final suffix. The dummy head is especially valuable because it eliminates the awkward question, "Is this the first result node?" Every real node follows the same attach-and-advance pattern.

Edge-case checklist

  • If both lists are empty, dummy.next is null.
  • If one list is empty, link the other list immediately.
  • If all values in one list are smaller, the other list becomes the remainder.
  • Equal values still require advancing exactly one pointer.

Common pitfall

Not using a dummy node forces awkward special-casing of the first element and often creates a separate, error-prone initialization branch.

Micro-example For [] and [0], the loop never runs. The remainder assignment sets dummy.next to the node containing 0, so the answer is [0].

Pitfalls

  • Reading a.val or b.val after that pointer became null.
  • Returning the dummy instead of dummy.next.
  • Detaching the remainder by overwriting a needed next pointer.

Recap

  • Let null checks guard every comparison.
  • Let the dummy handle the first insertion.
  • Link, do not copy, the sorted remainder.

Pitfalls and Edge Cases

Why is returning `dummy` incorrect after the merge?

Complexity and Wrap-up

Learning goal: Explain why dummy-head merging is optimal for the required time and space bounds.

Core idea Each node is attached once and each input pointer moves only forward. Therefore, the loop performs at most n + m comparisons or attachments, where n and m are the input lengths. The algorithm stores only a few pointers; it does not allocate an array or recursion stack.

Complexity analysis

ComponentCostReason
Main merge loopO(n + m)Each node is visited at most once
Remainder linkO(1)One pointer assignment
Auxiliary spaceO(1)Only dummy, tail, a, and b

Micro-example For lengths 3 and 3, at most six nodes are processed. The result reuses those same six nodes, so extra storage stays constant.

Pitfalls

  • Calling the result construction O(n + m) space when nodes are reused is incorrect.
  • Counting the dummy as an input node changes neither bound.
  • A recursive implementation may use O(n + m) call-stack space, unlike this iterative approach.

Recap

  • Time: O(n + m).
  • Extra space: O(1).
  • Dummy plus two moving input pointers gives clean, optimal weaving.

Complexity and Wrap-up

Summarizes the cost of the iterative merge.

Complexity analysis
Time
O(n + m)
Space
O(1)
Where the time goes
  • Compare and attach nodesEach node enters the merged chain once.O(n + m)
  • Link the remaining suffixOne final pointer assignment.O(1)
  • Pointer storageThe algorithm uses a fixed number of references.O(1)
How it grows
input size n →opsO(n²)O(n log n)O(n)O(log n)O(1)

The iterative dummy-head method is optimal because it must inspect the input nodes and uses constant auxiliary space.

Now try it on your own problem

Paste any LeetCode problem — or one of your own — and codebrew builds a walkthrough like this one for it.

Build a lesson from any problem

Related problems