LeetCode ยท #21

Merge Two Sorted Lists Solution

Merge two sorted linked lists into one sorted linked list by splicing their nodes together.

01
Section One ยท Problem

Problem Statement

๐Ÿท๏ธ

Difficulty

Easy

๐Ÿ”—

LeetCode

Problem #21

๐Ÿ—๏ธ

Pattern

Merge โ€” dummy head technique

Given the heads of two sorted linked lists list1 and list2, merge them into one sorted list made by splicing together the nodes of the two lists. Return the head of the merged list.

Example
Input: list1 = 1โ†’2โ†’4, list2 = 1โ†’3โ†’4 Output: 1โ†’1โ†’2โ†’3โ†’4โ†’4
Constraints
โ€ข 0 โ‰ค list length โ‰ค 50 โ€ข -100 โ‰ค Node.val โ‰ค 100 โ€ข Both lists are sorted in non-decreasing order
02
Section Two ยท Approach 1

Collect & Sort โ€” O(n log n)

Collect all values into an array, sort, and build a new list. Wastes the fact that both lists are already sorted.

Problem: O(n log n) sorting is unnecessary. A single pass comparing heads of both lists โ€” like merge sort's merge step โ€” gives O(n+m).
03
Section Three ยท Approach 2

Iterative Merge โ€” O(n + m)

Create a dummy head node. Compare the current heads of both lists, link the smaller one to the merged list, and advance that pointer. When one list is exhausted, link the remainder of the other.

๐Ÿ’ก Mental model: Two sorted stacks of exam papers. Pick up the top paper from whichever stack has the smaller grade number, place it on your merged pile. When one stack runs out, dump the rest of the other stack onto the pile.
Algorithm
  • Step 1: Create dummy = new ListNode(0), tail = dummy.
  • Step 2: While both lists non-null: compare values, link smaller to tail, advance that list pointer.
  • Step 3: Link remaining non-null list to tail.
  • Step 4: Return dummy.next.
๐ŸŽฏ Dummy head trick:
  • The dummy node avoids special-casing the first insertion.
  • Without it, you'd need an if-statement to set the head of the result.
  • With it, you always link to tail.next and return dummy.next.
  • This trick appears in most linked-list merge/build problems.
04
Section Four ยท Trace

Visual Walkthrough

Trace: list1 = 1โ†’2โ†’4, list2 = 1โ†’3โ†’4:

Iterative merge โ€” compare heads, link smaller
LIST 1 1 2 4 LIST 2 1 3 4 MERGE STEPS โ€” pick smaller head each time โ‘  1(L1) โ‰ค 1(L2) โ†’ link 1 from L1. Advance L1โ†’2 โ‘ก 1(L2) โ‰ค 2(L1) โ†’ link 1 from L2. Advance L2โ†’3 โ‘ข 2(L1) โ‰ค 3(L2) โ†’ link 2. Advance L1โ†’4 โ‘ฃ 3(L2) โ‰ค 4(L1) โ†’ link 3. Advance L2โ†’4 โ‘ค 4(L1) โ‰ค 4(L2) โ†’ link 4. Advance L1โ†’null โ‘ฅ L1 exhausted โ†’ link remaining L2: 4 MERGED LIST 1 โ†’ 1 โ†’ 2 โ†’ 3 โ†’ 4 โ†’ 4 Answer: 1โ†’1โ†’2โ†’3โ†’4โ†’4 โœ“
05
Section Five ยท Implementation

Code โ€” Java & Python

Java โ€” Iterative Merge
class Solution { public ListNode mergeTwoLists(ListNode l1, ListNode l2) { ListNode dummy = new ListNode(0); ListNode tail = dummy; while (l1 != null && l2 != null) { if (l1.val <= l2.val) { tail.next = l1; l1 = l1.next; } else { tail.next = l2; l2 = l2.next; } tail = tail.next; } tail.next = (l1 != null) ? l1 : l2; return dummy.next; } }
Python โ€” Iterative Merge
class Solution: def mergeTwoLists(self, l1, l2): dummy = tail = ListNode(0) while l1 and l2: if l1.val <= l2.val: tail.next = l1 l1 = l1.next else: tail.next = l2 l2 = l2.next tail = tail.next tail.next = l1 or l2 return dummy.next
06
Section Six ยท Analysis

Complexity Analysis

ApproachTimeSpaceTrade-off
Iterative Merge โ† optimal O(n + m) O(1) In-place splicing with dummy head
RecursiveO(n + m)O(n + m)Clean code but O(n+m) stack depth
07
Section Seven ยท Edge Cases

Edge Cases & Pitfalls

CaseInputWhy It Matters
Both emptynull, nullLoop doesn't execute, tail.next = null โ†’ return null.
One emptynull, 1โ†’2Loop skips, tail.next = l2 โ†’ return l2 directly.
Different lengths1โ†’2, 1โ†’2โ†’3โ†’4Shorter runs out first, rest linked in one step.
โš  Common Mistake: Forgetting to advance tail = tail.next after linking. Without it, every new node overwrites the same tail.next, and you only get the last linked node in the result.

โ† Back to Linked List problems