Difficulty: Easy · LeetCode 21
Problem
Merge two sorted linked lists into one sorted linked list.
Understanding the problem
Splice together nodes of the two lists in sorted order.
Intuition
Use a dummy head node and compare current nodes of both lists to splice smaller node.
Approach
Create
dummy = ListNode(),current = dummy.While both
list1andlist2exist:Append smaller node to
current.nextand advance that list pointer.Attach remaining non-empty list
current.next = list1 or list2.Return
dummy.next.
Naive Solution — Brute Force
Extract node values to an array, sort array, rebuild new linked list.
class Solution:
def mergeTwoLists(self, list1, list2):
values = []
while list1:
values.append(list1.val)
list1 = list1.next
while list2:
values.append(list2.val)
list2 = list2.next
values.sort()
dummy = ListNode()
current = dummy
for value in values:
current.next = ListNode(value)
current = current.next
return dummy.nextclass Solution {
public:
ListNode* mergeTwoLists(ListNode* list1, ListNode* list2) {
vector<int> values;
while (list1) {
values.push_back(list1->val);
list1 = list1->next;
}
while (list2) {
values.push_back(list2->val);
list2 = list2->next;
}
sort(values.begin(), values.end());
ListNode dummy;
ListNode* current = &dummy;
for (int value : values) {
current->next = new ListNode(value);
current = current->next;
}
return dummy.next;
}
};class Solution {
public ListNode mergeTwoLists(ListNode list1, ListNode list2) {
List<Integer> values = new ArrayList<>();
while (list1 != null) {
values.add(list1.val);
list1 = list1.next;
}
while (list2 != null) {
values.add(list2.val);
list2 = list2.next;
}
Collections.sort(values);
ListNode dummy = new ListNode();
ListNode current = dummy;
for (int value : values) {
current.next = new ListNode(value);
current = current.next;
}
return dummy.next;
}
}var mergeTwoLists = function(list1, list2) {
const values = [];
while (list1) {
values.push(list1.val);
list1 = list1.next;
}
while (list2) {
values.push(list2.val);
list2 = list2.next;
}
values.sort((a, b) => a - b);
const dummy = new ListNode();
let current = dummy;
for (const value of values) {
current.next = new ListNode(value);
current = current.next;
}
return dummy.next;
};Time: O((n + m) log(n + m)) · Space: O(n + m)
Optimized Code (Python 3)
class Solution:
def mergeTwoLists(self, list1, list2):
dummy = ListNode()
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
current.next = list1 or list2
return dummy.nextclass Solution {
public:
ListNode* mergeTwoLists(ListNode* list1, ListNode* list2) {
ListNode dummy;
ListNode* current = &dummy;
while (list1 && list2) {
if (list1->val <= list2->val) {
current->next = list1;
list1 = list1->next;
} else {
current->next = list2;
list2 = list2->next;
}
current = current->next;
}
current->next = list1 ? list1 : list2;
return dummy.next;
}
};class Solution {
public ListNode mergeTwoLists(ListNode list1, ListNode list2) {
ListNode dummy = new ListNode();
ListNode current = dummy;
while (list1 != null && list2 != null) {
if (list1.val <= list2.val) {
current.next = list1;
list1 = list1.next;
} else {
current.next = list2;
list2 = list2.next;
}
current = current.next;
}
current.next = list1 != null ? list1 : list2;
return dummy.next;
}
}var mergeTwoLists = function(list1, list2) {
const dummy = new ListNode();
let current = dummy;
while (list1 && list2) {
if (list1.val <= list2.val) {
current.next = list1;
list1 = list1.next;
} else {
current.next = list2;
list2 = list2.next;
}
current = current.next;
}
current.next = list1 || list2;
return dummy.next;
};Time: O(n + m) · Space: O(1)
Takeaway
Pattern — Dummy Node + Two Pointer Splice