Merge K Sorted Arrays
Keep one candidate per array in a min-heap: its first unused element. Pop the smallest candidate and output it. Then push the next element from the same array. The heap never holds more than K items, because each array contributes only one candidate at a time.
The smallest unused element overall is always the smallest of the first unused elements of the arrays, so the heap top is always the correct next output.
Problem
You get K arrays. Each array is already sorted from smallest to largest. The arrays can have different lengths, and one of them can be empty.
Merge them into one array that holds every element, in sorted order.
arr: a list of K sorted arrays. K: how many arrays there are.
One sorted array that holds every element of every input array.
The smallest front value is 0 (from the third array), then 1, then 2, and so on. All 10 elements end up in order.
The empty array has nothing to add, so it is skipped.
- β’ Each input array is sorted from smallest to largest.
- β’ The arrays can have different lengths, and an array can be empty.
- β’ The values are integers.
First, think yourself
Before opening any solution, try to answer these on paper. Use hints only when stuck β each hint is counted.
- 1.
Each array is already sorted. Which element can be the very next one I output?
- 2.
If I only look at the first unused element of each array, how many candidates do I have at any moment?
- 3.
After I take an element out of an array, which element of that same array becomes a candidate?
- 4.
Which data structure gives me the smallest of my candidates quickly, and how big does it need to be?
- 5.
If I put all N elements into that structure at the start, does it still do the job?
Brute force approach
Better approach
Optimized approach
Why does this algorithm work?
Dry run
All approaches compared
| Approach | Idea | Time | Space |
|---|---|---|---|
| Brute Force | Copy every element into one list, then sort the whole list | O(N log N) | O(N) |
| Better | Merge the result with the next array, like merge sort's merge step | O(N Β· K) | O(N) |
| Optimal | Keep the first unused element of each array in a min-heap; pop the smallest, then push its successor | O(N log K) | O(K) |
Why does this belong to this pattern?
- βK sorted arraysβEach array is sorted, so only its first unused element can be the next output from it. That is why K candidates are enough.
- βmerge into one sorted arrayβAt every step, take the smallest of the candidates β a min-heap of the front values.
- βevery element appears onceβEach element is pushed and popped once, so the cost is N pushes and pops, not one per array.
Merging two sorted arrays needs one comparison per step: the two fronts. With K arrays, the next value is the smallest of K fronts, so we keep a min-heap of K candidates. The key move is pop, then push that array's successor. Push nothing else. Merge K Sorted Lists uses the same heap on linked lists, and Sort a Nearly Sorted Array uses it with a window of k + 1 items.
Don't make this mistake
The output is still sorted, so this looks right. But the heap now starts with all 10 elements instead of 3. That is just heap sort, O(N log N), and it throws away the idea that each array offers one candidate at a time. Push only the first element of each array.
On the dry run the heads are 2, 1 and 0. A max-heap pops 2 first, then keeps taking the largest head from each array. It outputs 2 6 9 1 5 8 0 3 4 7, which is not sorted. greater<> turns the heap into a min-heap.
The heap only ever holds the first unused element of each array. Without the push, it empties after 3 pops. On the dry run the output would be just [0, 1, 2].
An empty array has no element 0. Reading it is undefined behaviour and often crashes. Check the size before reading the first element.
Want to implement this?
Write it yourself on GeeksforGeeks, then come back and compare your code with the solutions above.
Open coding workspaceHow this concept connects to System Design & C++ Systems
Top engineering interviews test whether you understand how algorithms like K-way Merge translate into production architectures and low-level memory mechanics.
Foundations: Object-Oriented Principles in C++23
Class invariants, pure virtual interfaces, and RAII smart pointers.
Food Delivery System (Zomato Architecture)
Real-world machine coding application of algorithms and design patterns.
Pointers vs References Deep Dive
Pointer arithmetic and memory layout under the hood.
Virtual Method Table (vtable) & Memory Layout
Polymorphism, vptr overhead, and multiple inheritance in memory.