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.
The optimal solution uses a min-heap to efficiently merge all k sorted lists.
For lists: [[1,4,5], [1,3,4], [2,6]]
1/**
2 * Merge K Sorted Lists - Min-Heap Approach
3 *
4 * Time Complexity: O(N log k) where N is total nodes, k is number of lists
5 * Space Complexity: O(k) for the heap
6 */
7
8import java.util.*;
9
10class ListNode {
11 int val;
12 ListNode next;
13 ListNode() {}
14 ListNode(int val) { this.val = val; }
15 ListNode(int val, ListNode next) { this.val = val; this.next = next; }
16}
17
18class Solution {
19 public ListNode mergeKLists(ListNode[] lists) {
20 // Edge case: empty lists
21 if (lists == null || lists.length == 0) {
22 return null;
23 }
24
25 // Initialize min-heap with custom comparator
26 PriorityQueue<ListNode> minHeap = new PriorityQueue<>(
27 (a, b) -> a.val - b.val
28 );
29
30 // Add first node from each non-empty list
31 for (ListNode head : lists) {
32 if (head != null) {
33 minHeap.offer(head);
34 }
35 }
36
37 // Create dummy node for result
38 ListNode dummy = new ListNode(0);
39 ListNode current = dummy;
40
41 // Process heap until empty
42 while (!minHeap.isEmpty()) {
43 // Extract minimum node
44 ListNode minNode = minHeap.poll();
45
46 // Add to result list
47 current.next = minNode;
48 current = current.next;
49
50 // If extracted node has a next, add it to heap
51 if (minNode.next != null) {
52 minHeap.offer(minNode.next);
53 }
54 }
55
56 return dummy.next;
57 }
58}
59
60// Alternative: Divide and Conquer
61class Solution2 {
62 public ListNode mergeKLists(ListNode[] lists) {
63 if (lists == null || lists.length == 0) {
64 return null;
65 }
66
67 List<ListNode> listList = new ArrayList<>(Arrays.asList(lists));
68
69 // Merge lists in pairs until only one remains
70 while (listList.size() > 1) {
71 List<ListNode> mergedLists = new ArrayList<>();
72
73 // Merge pairs
74 for (int i = 0; i < listList.size(); i += 2) {
75 ListNode l1 = listList.get(i);
76 ListNode l2 = i + 1 < listList.size() ? listList.get(i + 1) : null;
77 mergedLists.add(mergeTwoLists(l1, l2));
78 }
79
80 listList = mergedLists;
81 }
82
83 return listList.get(0);
84 }
85
86 private ListNode mergeTwoLists(ListNode l1, ListNode l2) {
87 ListNode dummy = new ListNode(0);
88 ListNode current = dummy;
89
90 while (l1 != null && l2 != null) {
91 if (l1.val < l2.val) {
92 current.next = l1;
93 l1 = l1.next;
94 } else {
95 current.next = l2;
96 l2 = l2.next;
97 }
98 current = current.next;
99 }
100
101 current.next = l1 != null ? l1 : l2;
102 return dummy.next;
103 }
104}
105