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.
solution
We use a heap to keep track of the next value that we need to append to our output linked list. Then, use a hashmap to keep track of actual node addresses based on each list, because we can’t put the actual node objects into our heap.
class Solution:
def mergeKLists(self, lists: List[Optional[ListNode]]) -> Optional[ListNode]:
if not lists:
return None
dummy = ListNode(-1)
cur = dummy
heap = []
# idx of list in lists -> node object of current pointer in list
list_pointers = defaultdict()
for i, node in enumerate(lists):
if node:
heap.append((node.val, i))
list_pointers[i] = node
heapq.heapify(heap)
while heap:
# pop from heap and get node
val, list_idx = heapq.heappop(heap)
node = list_pointers[list_idx]
# append to result and advance cur pointer
cur.next = node
cur = cur.next
# find next node to put in heap from this list
next_node = node.next
list_pointers[list_idx] = next_node
if next_node:
heapq.heappush(heap, (next_node.val, list_idx))
return dummy.nextAlternatively, we can also use a list to store the addresses of the actual nodes.
def mergeKLists(self, lists: List[Optional[ListNode]]) -> Optional[ListNode]:
dummy = ListNode()
# heap[i] = [node.val, index of list that the node is in]
cur_pointers = []
minheap = []
# add all first values to heap
# add all pointers to array
for i, l in enumerate(lists):
if l:
heappush(minheap, (l.val, i))
cur_pointers.append(l)
curnode = dummy
while minheap:
next_val, list_idx = heappop(minheap)
# add value to output list
curnode.next = cur_pointers[list_idx]
curnode = curnode.next
# add next value in the list onto heap if it exists
cur_pointers[list_idx] = cur_pointers[list_idx].next
if cur_pointers[list_idx] is not None:
heappush(minheap, (cur_pointers[list_idx].val, list_idx))
return dummy.next