Merge K Sorted Array
Problem Statement:
Given k sorted arrays arranged in the form of a matrix of size k * k. The task is to merge them into one sorted array. Return the merged sorted array ( as a pointer to the merged sorted arrays in cpp, as an ArrayList in java, and list in python).
-
Example:
Examples :
Input:k = 3, arr[][] = {{1,2,3},{4,5,6},{7,8,9}}
Output:1 2 3 4 5 6 7 8 9
Explanation:Above test case has 3 sorted arrays of size 3, 3, 3 arr[][] = [[1, 2, 3],[4, 5, 6],[7, 8, 9]]. The merged list will be [1, 2, 3, 4, 5, 6, 7, 8, 9].Input:k = 4, arr[][]={{1,2,3,4},{2,2,3,4},{5,5,6,6},{7,8,9,9}}
Output:1 2 2 2 3 3 4 4 5 5 6 6 7 8 9 9
Explanation:Above test case has 4 sorted arrays of size 4, 4, 4, 4 arr[][] = [[1, 2, 2, 2], [3, 3, 4, 4], [5, 5, 6, 6], [7, 8, 9, 9 ]]. The merged list will be [1, 2, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 8, 9, 9].
Solution: Min-Heap (K-way merge)
// Technique: Min-Heap (K-way merge)
// Time: O(N log K), Space: O(K) + O(N) for output
class Solution {
public:
// pair format: (value, (array_index, element_index))
typedef pair<int, pair<int, int>> pp;
// Function to merge k sorted arrays.
vector<int> mergeKArrays(vector<vector<int>> arr, int K) {
vector<int> res;
if (K == 0 || arr.empty()) return res;
// Use actualK = min(K, arr.size()) in case K doesn't match arr.size()
int actualK = min(K, static_cast<int>(arr.size()));
// Min-heap: smallest value at top (lexicographic compare on pair).
priority_queue<pp, vector<pp>, greater<pp>> minHeap;
// Optionally compute total size to reserve result capacity and avoid reallocations
size_t total = 0;
for (int i = 0; i < actualK; ++i) total += arr[i].size();
if (total) res.reserve(total);
// Push first element of each non-empty array
for (int i = 0; i < actualK; ++i) {
if (!arr[i].empty()) {
minHeap.push({ arr[i][0], { i, 0 } });
}
}
// Extract min and push next element from same array until heap empties
while (!minHeap.empty()) {
auto it = minHeap.top();
minHeap.pop();
int val = it.first; // smallest value
int i = it.second.first; // which array
int j = it.second.second; // index in that array
res.push_back(val);
// If next element exists in same array, push it
if (j + 1 < static_cast<int>(arr[i].size())) {
minHeap.push({ arr[i][j + 1], { i, j + 1 } });
}
}
return res;
}
};
✅ Label the code solution
Technique: Min-Heap (K-way merge using a min priority queue)
📝 How It Works
- Build a min-heap that stores a triple
(value, (array_index, element_index))for the current candidate from each array. - Initially push the first element of every non-empty array into the heap.
- Repeatedly:
- Pop the smallest triple
(val, (i, j))from the heap. - Append
valto the result vector. - From the same array
i, if indexj+1exists, push(arr[i][j+1], (i, j+1))into the heap.
- Pop the smallest triple
- Stop when the heap is empty. Because the heap always yields the smallest available value across all arrays, the output is globally sorted.
🧩 Key Formula / Recurrence
- Not recursive; the key transition is:
pop (val, (i,j))→push (arr[i][j+1], (i,j+1))if exists.
- Each element triggers at most one push and one pop; heap operations cost
O(log K).
⏱️ Time & Space Complexity
- Time:
O(N log K)N= total number of elements across all arrays.- Each of the
Nelements is inserted and removed from the heap once; each heap op isO(log K).
- Space:
O(K)extra for the heap plusO(N)for the output vectorres(output space excluded from "extra" if you prefer).
⚠️ Edge Cases
K == 0orarrempty → return empty vector.- Some arrays may be empty — they are skipped on initial push.
Kpassed can be larger thanarr.size()— code usesactualK = min(K, arr.size()).- Arrays of varying lengths work fine.
- Duplicate values — stable ordering between equal values is by insertion order into heap (not strictly necessary to guarantee beyond sorting).
- Very large total
N— reservingrescapacity (done) reduces reallocations.
💡 Other Approaches
- Divide & Conquer (Pairwise merge)
- Merge arrays in pairs repeatedly (like tournament).
- Time:
O(N log K). May be faster in practice due to less heap overhead; needs extra space for merged results.
- Flatten & Sort
- Concatenate all arrays then
std::sort. - Time:
O(N log N), Space:O(N). Simpler but often slower whenKis much smaller thanN.
- Concatenate all arrays then
- External Multiway Merge
- For datasets that don't fit in memory: read chunks, produce sorted runs, use k-way merge with limited memory buffers (external sorting).
🔁 Related Problems
- Merge k Sorted Lists (LeetCode 23) — same concept for linked lists.
- Merge Two Sorted Arrays / Lists (LeetCode 21) — primitive building block.
- Smallest Range Covering Elements from K Lists (LeetCode 632) — also uses a min-heap over k sources.
🛠️ Other Notes (optional but recommended)
- C++ by default (done).
- Inline comments included in the code.
- Real-world analogy: Think of
Kconveyor belts each outputting sorted items; you always pick the smallest visible item across belts — the min-heap is the efficient "smallest-finder". - Avoid unnecessary boilerplate: function provided is ready to drop into typical competitive templates.
💬