Introduction
LeetCode 21: Merge Two Sorted Lists is a classic linked list problem. Given two sorted singly linked lists, the task is to merge them into one sorted list.
This is a foundational problem that demonstrates how to traverse and manipulate linked lists efficiently in Go.
Problem Statement
You are given the heads of two sorted linked lists list1 and list2. Merge the two lists in a way that the resulting list is also sorted and return its head.
Examples
go
Input: list1 = [1,2,4], list2 = [1,3,4]
Output: [1,1,2,3,4,4]
go
Input: list1 = [], list2 = []
Output: []
go
Input: list1 = [], list2 = [0]
Output: [0]
Approach: Iterative Merge with Dummy Node
- Use a dummy node to simplify edge cases and hold the merged list.
- Use a tail pointer to build the new list as you compare nodes from both lists.
- Traverse both lists:
- Always attach the smaller node to
tail.Next.
- Move the corresponding pointer forward.
- Once one list ends, attach the rest of the other list to
tail.Next.
Go Implementation
go
package main
import (
"fmt"
)
// Definition for singly-linked list.
type ListNode struct {
Val int
Next *ListNode
}
func mergeTwoLists(list1 *ListNode, list2 *ListNode) *ListNode {
dummy := &ListNode{}
tail := dummy
for list1 != nil && list2 != nil {
if list1.Val < list2.Val {
tail.Next = list1
list1 = list1.Next
} else {
tail.Next = list2
list2 = list2.Next
}
tail = tail.Next
}
if list1 != nil {
tail.Next = list1
} else {
tail.Next = list2
}
return dummy.Next
}
Helper Functions for Testing
go
// Converts slice to linked list
func createList(nums []int) *ListNode {
dummy := &ListNode{}
current := dummy
for _, val := range nums {
current.Next = &ListNode{Val: val}
current = current.Next
}
return dummy.Next
}
// Prints linked list
func printList(head *ListNode) {
for head != nil {
fmt.Print(head.Val)
if head.Next != nil {
fmt.Print(" -> ")
}
head = head.Next
}
fmt.Println()
}
func main() {
list1 := createList([]int{1, 2, 4})
list2 := createList([]int{1, 3, 4})
fmt.Print("List 1: ")
printList(list1)
fmt.Print("List 2: ")
printList(list2)
merged := mergeTwoLists(list1, list2)
fmt.Print("Merged List: ")
printList(merged)
}
Step-by-Step Example
Given:
ini
list1 = 1 → 2 → 4
list2 = 1 → 3 → 4
Merged process:
csharp
1 (from list1)
1 (from list2)
2 (from list1)
3 (from list2)
4 (from list1)
4 (from list2)
Result:
1 → 1 → 2 → 3 → 4 → 4
Time and Space Complexity
- Time Complexity: O(n + m), where n and m are the lengths of the two lists.
- Space Complexity: O(1), since we only use pointers and no extra data structures (excluding output list).
Key Takeaways
- This problem is a great example of using pointers to manipulate and merge linked structures.
- The dummy node pattern helps avoid special case handling for the head.
- You can also solve it recursively—great for interviews if you want to show alternate styles.