You are given the heads of two sorted linked lists list1
and list2
.
Merge the two lists into one sorted list. The list should be made by splicing together the nodes of the first two lists.
Return the head of the merged linked list.
Example 1:
Input: list1 = [1,2,4], list2 = [1,3,4] Output: [1,1,2,3,4,4]
Example 2:
Input: list1 = [], list2 = [] Output: []
Example 3:
Input: list1 = [], list2 = [0] Output: [0]
Constraints:
[0, 50]
.-100 <= Node.val <= 100
list1
and list2
are sorted in non-decreasing order.When you get asked this question in a real-life environment, it will often be ambiguous (especially at FAANG). Make sure to ask these questions in that case:
The simplest way to solve this is to first gather all the items from both lists into one single, large collection. Then, sort this combined collection from the smallest item to the largest to get the final merged list.
Here's how the algorithm would work step-by-step:
class ListNode:
def __init__(self, val=0, next=None):
self.val = val
self.next = next
def mergeTwoLists(list_one: ListNode, list_two: ListNode) -> ListNode:
all_values = []
current_node = list_one
while current_node is not None:
all_values.append(current_node.val)
current_node = current_node.next
current_node = list_two
while current_node is not None:
all_values.append(current_node.val)
current_node = current_node.next
# Sorting is necessary because the collection has values from both lists but is not ordered.
all_values.sort()
# A dummy head node simplifies building the new list by providing a fixed starting point.
head_of_merged_list = ListNode()
current_merged_node = head_of_merged_list
# We must iterate through the sorted values to construct the final linked list in order.
for value in all_values:
current_merged_node.next = ListNode(value)
current_merged_node = current_merged_node.next
return head_of_merged_list.next
The best way to solve this is to build a new, single sorted list by picking the smaller of the two front items from the original lists, one by one. This way, we always add the next smallest available item to our new list, guaranteeing it stays sorted without extra work.
Here's how the algorithm would work step-by-step:
class ListNode:
def __init__(self, val=0, next=None):
self.val = val
self.next = next
def mergeTwoLists(list_one, list_two):
# Create a dummy node to act as the starting point of the merged list.
dummy_head_node = ListNode()
current_merged_node = dummy_head_node
while list_one and list_two:
# Compare the front nodes of both lists to decide which one to add next.
if list_one.val < list_two.val:
current_merged_node.next = list_one
list_one = list_one.next
else:
current_merged_node.next = list_two
list_two = list_two.next
current_merged_node = current_merged_node.next
# If one list is exhausted, append the rest of the other list.
if list_one:
current_merged_node.next = list_one
elif list_two:
current_merged_node.next = list_two
return dummy_head_node.next
Case | How to Handle |
---|---|
One or both of the input lists are null or empty | The solution should return the other non-empty list, or null if both are empty. |
One list is exhausted while the other still has nodes | The remaining portion of the non-empty list is appended to the end of the merged list. |
Both lists contain only a single node | The two nodes are compared and linked correctly to form a new two-node sorted list. |
Both lists contain duplicate values, either within a list or across lists | The relative order of equal elements is preserved by the merge logic, ensuring a stable merge. |
The lists contain negative numbers and zeros | The standard comparison logic correctly handles negative numbers and zeros without special cases. |
One list is significantly longer than the other | The iterative approach efficiently handles this by simply appending the rest of the longer list once the shorter one is consumed. |
All elements in one list are smaller than all elements in the other | The solution will effectively append the second list to the end of the first list. |
Maximum-sized inputs leading to deep recursion | An iterative solution is preferred to avoid potential stack overflow errors that a naive recursive solution might face with very long lists. |