You are given an array of k
linked-lists lists
, each linked-list is sorted in ascending order.
Merge all the linked-lists into one sorted linked-list and return it.
Examples:
lists = [[1,4,5],[1,3,4],[2,6]]
Output: [1,1,2,3,4,4,5,6]
Explanation: The linked-lists are:
[
1->4->5,
1->3->4,
2->6
]
merging them into one sorted list:
1->1->2->3->4->4->5->6
lists = []
Output: []
lists = [[]]
Output: []
Constraints:
k == lists.length
0 <= k <= 10^4
0 <= lists[i].length <= 500
-10^4 <= lists[i][j] <= 10^4
lists[i]
is sorted in ascending order.lists[i].length
will not exceed 10^4
.Describe an algorithm to merge the k sorted lists into a single sorted list. Analyze the time and space complexity of your solution. What are some edge cases to consider?
One straightforward approach is to collect all the values from the linked lists into a single array, sort the array, and then create a new linked list from the sorted array.
Algorithm:
lists
.Code (Python):
class ListNode:
def __init__(self, val=0, next=None):
self.val = val
self.next = next
def mergeKLists(lists):
values = []
for linked_list in lists:
current = linked_list
while current:
values.append(current.val)
current = current.next
values.sort()
if not values:
return None
head = ListNode(values[0])
current = head
for i in range(1, len(values)):
current.next = ListNode(values[i])
current = current.next
return head
Time Complexity: O(N log N), where N is the total number of nodes in all linked lists. This is due to the sorting step.
Space Complexity: O(N), where N is the total number of nodes. This is because we store all node values in an array.
A more efficient approach is to use a priority queue (min-heap) to keep track of the smallest node from all the linked lists. This allows us to merge the lists in sorted order without explicitly sorting all the values at once.
Algorithm:
Code (Python):
import heapq
class ListNode:
def __init__(self, val=0, next=None):
self.val = val
self.next = next
def mergeKLists(lists):
heap = []
for node in lists:
if node:
heapq.heappush(heap, (node.val, node))
dummy = ListNode()
current = dummy
while heap:
val, node = heapq.heappop(heap)
current.next = node
current = current.next
if node.next:
heapq.heappush(heap, (node.next.val, node.next))
return dummy.next
Time Complexity: O(N log k), where N is the total number of nodes in all linked lists and k is the number of linked lists. Each insertion and extraction from the heap takes O(log k) time, and we perform these operations for each of the N nodes.
Space Complexity: O(k), where k is the number of linked lists. This is the space used by the priority queue.
lists
is empty, return None
.if node:
before pushing onto the heap.