Ruairí O'Brien

Posted on

# Day 24 - Merge k Sorted Lists

You are given an array of k linked-lists lists, each linked-list is sorted in ascending order.

Example 1:

Input: lists = [[1,4,5],[1,3,4],[2,6]]
Output: [1,1,2,3,4,4,5,6]
[
1->4->5,
1->3->4,
2->6
]
merging them into one sorted list:
1->1->2->3->4->4->5->6

Example 2:

Input: lists = []
Output: []

Example 3:

Input: 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.
• The sum of lists[i].length won't exceed 10^4.

## Tests

import pytest
from .util import toListNode, toList
from .Day24_MergeKSortedLists import Solution

s = Solution()

@pytest.mark.parametrize(
"lists,expected",
[([[1, 4, 5], [1, 3, 4], [2, 6]], [1, 1, 2, 3, 4, 4, 5, 6]), ([], []), ([[]], [])],
)
def test_merge_k_lists(lists, expected):
assert toList(s.mergeKLists(list(map(lambda x: toListNode(x), lists)))) == expected

@pytest.mark.parametrize(
"lists,expected",
[([[1, 4, 5], [1, 3, 4], [2, 6]], [1, 1, 2, 3, 4, 4, 5, 6]), ([], []), ([[]], [])],
)
def test_merge_k_lists2(lists, expected):
assert toList(s.mergeKLists2(list(map(lambda x: toListNode(x), lists)))) == expected

## Solution

from typing import List
from .util import ListNode
from queue import PriorityQueue

def mergeTwoLists(l1: ListNode, l2: ListNode) -> ListNode:
while l1 and l2:
if l1.val <= l2.val:
current.next = l1
l1 = l1.next
else:
current.next = l2
l2 = l1
l1 = current.next.next
current = current.next
current.next = l2 if l2 else l1

class Solution:
def build_queue(self, lists: List[ListNode]) -> PriorityQueue:
q = PriorityQueue()
for l in lists:
if l:
q.put((l.val, l))
return q

def mergeKLists2(self, lists: List[ListNode]) -> ListNode:
q = self.build_queue(lists)

while not q.empty():
val, list_node = q.get()
current.next = ListNode(val)
current = current.next
next_node = list_node.next
if next_node:
q.put((next_node.val, next_node))

def mergeKLists(self, lists: List[ListNode]) -> ListNode:
k = len(lists)
if k == 0:
return None

step = 1
while step < k:
for i in range(0, k - step, step * 2):
lists[i] = mergeTwoLists(lists[i], lists[i + step])
step *= 2

return lists[0]