|
| 1 | +# 23. Merge k Sorted Lists |
| 2 | + |
| 3 | +## link |
| 4 | +LeetCode: https://leetcode.com/problems/merge-k-sorted-lists/ |
| 5 | + |
| 6 | +## Pattern |
| 7 | + |
| 8 | +* Linked List |
| 9 | +* Divide and Conquer |
| 10 | +* Merge Sort |
| 11 | + |
| 12 | +## Idea |
| 13 | +### Rus |
| 14 | +Требуется объединить `k` отсортированных связных списков в один отсортированный список. |
| 15 | + |
| 16 | +Наивный подход — последовательно мержить каждый список с результатом предыдущих объединений. Однако в этом случае один и тот же узел может участвовать в слиянии много раз, что приводит к сложности около `O(N * k)`. |
| 17 | + |
| 18 | +Вместо этого используется подход **Divide and Conquer**, аналогичный Merge Sort. |
| 19 | + |
| 20 | +Сначала объединяются соседние списки попарно: |
| 21 | + |
| 22 | +```text |
| 23 | +L1 + L2 |
| 24 | +L3 + L4 |
| 25 | +L5 + L6 |
| 26 | +... |
| 27 | +``` |
| 28 | + |
| 29 | +После первого прохода количество списков уменьшается примерно вдвое. |
| 30 | + |
| 31 | +Затем объединяются уже полученные результаты: |
| 32 | + |
| 33 | +```text |
| 34 | +(L1+L2) + (L3+L4) |
| 35 | +(L5+L6) + (L7+L8) |
| 36 | +... |
| 37 | +``` |
| 38 | + |
| 39 | +Размер объединяемых групп удваивается на каждой итерации. Для этого используется переменная `interval`: |
| 40 | + |
| 41 | +```text |
| 42 | +interval = 1 |
| 43 | +interval = 2 |
| 44 | +interval = 4 |
| 45 | +interval = 8 |
| 46 | +... |
| 47 | +``` |
| 48 | + |
| 49 | +На каждом шаге выполняется: |
| 50 | + |
| 51 | +```java |
| 52 | +lists[i] = merge(lists[i], lists[i + interval]); |
| 53 | +``` |
| 54 | + |
| 55 | +Пока `interval` не станет больше количества списков. |
| 56 | + |
| 57 | +Для объединения двух отсортированных списков используется стандартный алгоритм с dummy-узлом и двумя указателями. |
| 58 | + |
| 59 | +В результате каждый уровень обработки проходит по всем узлам один раз, а количество уровней равно `log(k)`. |
| 60 | + |
| 61 | +### Eng |
| 62 | + |
| 63 | +We need to merge `k` sorted linked lists into a single sorted list. |
| 64 | + |
| 65 | +A naive approach is to merge the lists one by one into a growing result. However, this causes the same nodes to be processed multiple times, resulting in roughly `O(N * k)` complexity. |
| 66 | + |
| 67 | +Instead, we use a **Divide and Conquer** strategy similar to Merge Sort. |
| 68 | + |
| 69 | +First, we merge adjacent pairs of lists: |
| 70 | + |
| 71 | +```text |
| 72 | +L1 + L2 |
| 73 | +L3 + L4 |
| 74 | +L5 + L6 |
| 75 | +... |
| 76 | +``` |
| 77 | + |
| 78 | +After the first pass, the number of lists is reduced by approximately half. |
| 79 | + |
| 80 | +Then we merge the merged results: |
| 81 | + |
| 82 | +```text |
| 83 | +(L1+L2) + (L3+L4) |
| 84 | +(L5+L6) + (L7+L8) |
| 85 | +... |
| 86 | +``` |
| 87 | + |
| 88 | +The size of merged groups doubles after every iteration. This is controlled by the `interval` variable: |
| 89 | + |
| 90 | +```text |
| 91 | +interval = 1 |
| 92 | +interval = 2 |
| 93 | +interval = 4 |
| 94 | +interval = 8 |
| 95 | +... |
| 96 | +``` |
| 97 | + |
| 98 | +At each step we perform: |
| 99 | + |
| 100 | +```java |
| 101 | +lists[i] = merge(lists[i], lists[i + interval]); |
| 102 | +``` |
| 103 | + |
| 104 | +until `interval` becomes greater than or equal to the number of lists. |
| 105 | + |
| 106 | +The helper `merge()` function merges two sorted linked lists using the standard dummy-node technique. |
| 107 | + |
| 108 | +Since each level processes all nodes once and there are `log(k)` levels, the overall complexity is `O(N log k)`. |
| 109 | + |
| 110 | +## Complexity |
| 111 | + |
| 112 | +- Time: `O(N log k)` |
| 113 | +- Space: `O(1)` |
| 114 | + |
| 115 | +where: |
| 116 | + |
| 117 | +* `N` = total number of nodes across all lists |
| 118 | +* `k` = number of linked lists |
| 119 | + |
| 120 | +## Problems |
| 121 | + |
| 122 | +* Easy to forget the loop condition: |
| 123 | + |
| 124 | +```java |
| 125 | +i + interval < lists.length |
| 126 | +``` |
| 127 | + |
| 128 | +otherwise an index out of bounds error may occur. |
| 129 | + |
| 130 | +* Be careful not to create new nodes during merge. The solution should reuse existing nodes by updating `next` pointers. |
| 131 | + |
| 132 | +* The final answer is stored in: |
| 133 | + |
| 134 | +```java |
| 135 | +lists[0] |
| 136 | +``` |
| 137 | + |
| 138 | +after all merge rounds are completed. |
0 commit comments