Fade to Solo
Linked List

Merge Two Sorted Lists

STUDYEleetcode ↗

Problem

You're given the heads of two already-sorted linked lists. Splice them together into one sorted list, reusing the existing nodes, and return the new head.

Signal

Combining two already-sorted sequences into one sorted sequence, without extra scratch space, is a dummy-head-and-splice job — you never allocate new nodes, you just re-point next pointers as you walk both lists in lockstep.

Approach

Create a throwaway dummy node so the merged list always has a stable place to hang its first real node — this avoids a special case for "which list starts first". Keep a tail pointer at the end of the merged list so far. At each step, compare the two lists' current nodes, splice the smaller one onto tail.next, and advance both tail and that list's pointer. When one list runs out, splice the remainder of the other list on directly.

Skeleton

dummy = Node()
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
tail.next = list1 or list2
return dummy.next

Solution

class ListNode:
    def __init__(self, val=0, next=None):
        self.val = val
        self.next = next


def merge_two_lists(list1: ListNode | None, list2: ListNode | None) -> ListNode | None:
    dummy = ListNode()
    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

    tail.next = list1 if list1 else list2
    return dummy.next

Complexity

O(n + m) time — each node from both lists is visited exactly once. O(1) space — no new nodes allocated, just re-linked existing ones.

Pitfalls

  • Allocating brand-new nodes instead of re-linking the existing ones works but wastes O(n + m) space the interviewer likely wants you to avoid.
  • Forgetting the dummy head and trying to special-case "which list is the initial head" adds bug surface for no benefit.
  • Not attaching the leftover tail (list1 or list2) after the loop silently drops the remainder of the longer list.