The problem
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
Input: 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
Input: lists = []
Output: []
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
will not exceed10^4
.
Brute Force Solution
func mergeKLists(_ lists: [ListNode?]) -> ListNode? {
var nodes: [Int] = []
// Step 1
for i in 0..<lists.count {
var lst = lists[i]
while lst != nil {
nodes.append(lst!.val)
lst = lst?.next
}
}
// Step 2
nodes.sort()
// Step 3
var res = ListNode(0)
var curr: ListNode? = res
for node in nodes {
curr?.next = ListNode(node)
curr = curr?.next
}
return res.next
}
Explanation
We can solve this problem by separating it into three steps:
- Find all node values in the
lists
: This way, we can create an unsorted single list. - Sort the created list: This allows us to form a sorted linked list.
- Create a sorted linked list from the sorted values.
Time/Space Complexity
- Time complexity:
O(n * m)
wheren
is the length oflists
andm
is the length of the linked lists. - Space complexity:
O(n)
.
Solution 2
func mergeKLists(_ lists: [ListNode?]) -> ListNode? {
if lists.isEmpty {
return nil
}
var lists = lists
while lists.count > 1 {
var mergedLists: [ListNode?] = []
for i in stride(from: 0, to: lists.count, by: 2) {
var l1 = lists[i]
var l2: ListNode?
if i + 1 < lists.count {
l2 = lists[i + 1]
}
mergedLists.append(merge(l1, l2))
}
lists = mergedLists
}
return lists[0]
}
func merge(_ l1: ListNode?, _ l2: ListNode?) -> ListNode? {
let dummyNode = ListNode()
var l1 = l1
var l2 = l2
var tail: ListNode? = dummyNode
while l1 != nil && l2 != nil {
if l1!.val < l2!.val {
tail?.next = l1
l1 = l1!.next
} else {
tail?.next = l2
l2 = l2!.next
}
tail = tail?.next
}
tail?.next = l1 ?? l2
return dummyNode.next
}
Explanation
We can solve this problem by dividing it into sub-problems:
- Find the first and second linked lists:
- Iterate through
lists.count
until it equals1
, usingstride
withstep = 2
to find the first and second portions of the linked lists.
- Iterate through
- Merge them:
- Use the merge function for linked lists, which is a common problem in itself.
Time/Space Complexity
- Time complexity:
O(n * log k)
- Space complexity:
O(k)
Wherek
is the total number of lists, andn
is the total number of nodes acrossk
lists.