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.This problem involves merging two sorted linked lists into a single sorted linked list. We'll explore two approaches: recursion and iteration.
This approach elegantly solves the problem using recursion. The core idea is to compare the heads of the two input lists (list1
and list2
). The smaller head is chosen to be the head of the merged list, and the function recursively calls itself to merge the remaining parts of the two lists.
Algorithm:
list1
or list2
is empty, return the non-empty list (or null
if both are empty).list1.val <= list2.val
, recursively merge list1.next
and list2
. The result becomes the next
node of list1
. Return list1
.list1
and list2.next
. The result becomes the next
node of list2
. Return list2
.Time Complexity: O(m + n), where 'm' and 'n' are the lengths of the two input lists. Each node is visited once.
Space Complexity: O(m + n) in the worst case due to the recursive call stack depth, which can be equal to the length of the longer list.
This approach uses an iterative method, making it more efficient in terms of space complexity compared to the recursive approach.
Algorithm:
dummy
) to simplify the handling of the merged list's head.curr
) to the dummy node.list1
and list2
are not empty:
list1.val
and list2.val
.curr.next
and advance the corresponding list pointer.curr
to the newly added node.curr.next
.dummy.next
(the head of the merged list).Time Complexity: O(m + n). Each node is visited once.
Space Complexity: O(1). Constant extra space is used regardless of input size.
Recursive Approach:
class ListNode:
def __init__(self, val=0, next=None):
self.val = val
self.next = next
def mergeTwoListsRecursive(list1, list2):
if not list1:
return list2
if not list2:
return list1
if list1.val <= list2.val:
list1.next = mergeTwoListsRecursive(list1.next, list2)
return list1
else:
list2.next = mergeTwoListsRecursive(list1, list2.next)
return list2
Iterative Approach:
def mergeTwoListsIterative(list1, list2):
dummy = ListNode()
curr = dummy
while list1 and list2:
if list1.val <= list2.val:
curr.next = list1
list1 = list1.next
else:
curr.next = list2
list2 = list2.next
curr = curr.next
curr.next = list1 or list2 # Append remaining nodes
return dummy.next
The iterative approach is generally preferred because of its better space complexity. However, the recursive solution is often considered more concise and easier to understand for those comfortable with recursion. Choose the approach that best suits your needs and coding style. The code examples in other languages will follow a similar structure to these Python examples.