21. Merge Two Sorted Lists#
Difficulty: Easy
Link to Problem: To see the Merge Two Sorted Lists problem on LeetCode, click here!
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.
Constraints:
The number of nodes in both lists is in the range
[0, 50]
.-100 <= Node.val <= 100
Both
list1
andlist2
are sorted in non-decreasing order.
class ListNode:
def __init__(self, val=0, next=None):
self.val = val
self.next = next
def mergeTwoLists(list1, list2):
# Create a dummy node to simplify the code.
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
# Append the remaining elements from either list.
if list1:
current.next = list1
else:
current.next = list2
return dummy.next
Explanation:#
We define a class
ListNode
to represent the nodes of a singly-linked list. Each node has aval
attribute to store the value of the node and anext
attribute to point to the next node in the list.We define the
mergeTwoLists
function that takes two linked list heads,list1
andlist2
, as input.We create a
dummy
node at the beginning of the merged list. Thedummy
node simplifies the code by serving as a placeholder, and itsnext
attribute will point to the actual merged list.We initialize a
current
pointer to point to thedummy
node initially. Thiscurrent
pointer helps us traverse and build the merged list.We enter a
while
loop that continues until eitherlist1
orlist2
becomes empty. Inside the loop, we compare the values of the nodes at the current positions oflist1
andlist2
.If the
val
of the node inlist1
is smaller than theval
of the node inlist2
, we attach the node fromlist1
to the merged list by updating thenext
attribute of thecurrent
node to point to the node inlist1
. We then move thelist1
pointer to the next node.If the
val
of the node inlist2
is smaller than or equal to theval
of the node inlist1
, we attach the node fromlist2
to the merged list in a similar manner. We move thelist2
pointer to the next node.After attaching a node to the merged list, we move the
current
pointer to the newly added node. This step is essential for keeping track of the end of the merged list.The loop continues until either
list1
orlist2
becomes empty.Once the loop exits, we check if there are any remaining elements in
list1
orlist2
. Iflist1
is not empty, we attach the remaining elements oflist1
to the merged list. Iflist2
is not empty, we attach the remaining elements oflist2
.Finally, we return the
next
attribute of thedummy
node as the head of the merged list, which represents the sorted merged list.
# Helper function to print the linked list
def printLinkedList(head):
result = []
while head:
result.append(head.val)
head = head.next
return result
Let’s explain the helper functions: printLinkedList Function:
The
printLinkedList
function takes thehead
of a linked list as input and returns a list of values representing the nodes in the linked list.Inside the function, a
result
list is initialized to store the values of the linked list nodes.The function then iterates through the linked list starting from the
head
node and appends theval
attribute of each node to theresult
list.As it iterates through the list, it moves to the next node using the
next
attribute of each node.Finally, the function returns the
result
list containing the values of the linked list nodes in the order they appear in the linked list.
This function is useful for debugging and displaying the contents of a linked list. It allows you to easily convert a linked list into a regular Python list for visualization and testing purposes.
Test cases#
# Example 1:
# Input: list1 = [1,2,4], list2 = [1,3,4]
list1 = ListNode(1, ListNode(2, ListNode(4)))
list2 = ListNode(1, ListNode(3, ListNode(4)))
merged_list = mergeTwoLists(list1, list2)
printLinkedList(merged_list)
[1, 1, 2, 3, 4, 4]
# Example 2:
# Input: list1 = [], list2 = []
list1 = None
list2 = None
merged_list = mergeTwoLists(list1, list2)
printLinkedList(merged_list)
[]
# Example 3:
# list1 = [], list2 = [0]
list1 = None
list2 = ListNode(0)
merged_list = mergeTwoLists(list1, list2)
printLinkedList(merged_list)
[0]
Let’s analyze the time and space complexity of the mergeTwoLists
function.
Time Complexity:
The time complexity of this function is \(O(N + M\)), where \(N\) and \(M\) are the lengths of list1
and list2
, respectively. Here’s why:
In the worst case, we need to traverse both
list1
andlist2
completely. This involves iterating through all the nodes in both lists once.The while loop runs until either
list1
orlist2
becomes empty. The number of iterations depends on the total number of nodes in both lists, which is N + M in the worst case.Inside the loop, we perform constant-time operations for each iteration, such as comparisons and updating pointers.
Therefore, the dominant factor in the time complexity is the combined length of both input lists, resulting in a linear time complexity of \(O(N + M)\).
Space Complexity:
The space complexity of this function is \(O(1)\), which means it uses a constant amount of extra space regardless of the input sizes. Here’s why:
We create a few extra pointers (
dummy
,current
) and temporary variables (val
) to manage the merging process. These consume a fixed amount of memory, regardless of the input sizes. The number of these extra variables is independent of the lengths oflist1
andlist2
.We do not create a new data structure or allocate memory for the merged list. Instead, we rearrange the existing nodes from
list1
andlist2
to form the merged list. This operation does not consume additional memory proportional to the input sizes.
In summary, the mergeTwoLists
function has a time complexity of \(O(N + M)\) and a space complexity of \(O(1)\), making it an efficient solution for merging two sorted linked lists.
Challenging Exercises:#
Merge K Sorted Lists: Extend the problem to merge \(K\) sorted linked lists instead of just two. You need to efficiently merge \(K\) lists into one sorted list.
Merge Lists in a Zigzag Pattern: Merge two sorted lists in a zigzag pattern. For example, given [1, 2, 4] and [1, 3, 5], the merged list should be [1, 1, 2, 3, 4, 5].