Merging two sorted arrays is a fundamental algorithm used as a building block in merge sort and many other applications. This O(n + m) solution uses the two-pointer technique to efficiently combine arrays while maintaining sorted order.
function mergeSortedArrays(arr1, arr2) { const merged = []; let i = 0, j = 0; while (i < arr1.length && j < arr2.length) { if (arr1[i] <= arr2[j]) { merged.push(arr1[i++]); } else { merged.push(arr2[j++]); } } // Append remaining elements while (i < arr1.length) merged.push(arr1[i++]); while (j < arr2.length) merged.push(arr2[j++]); return merged; }
mergeSortedArrays([1, 3, 5], [2, 4, 6]); // โ [1, 2, 3, 4, 5, 6]
O(n + m) โ linear in total elementsFor merging more than two arrays, we can use a min-heap approach for optimal performance.
Given an array of sorted arrays, merge them into one fully sorted array efficiently.
We need to efficiently get the smallest item across all arrays โ a min-heap (priority queue) is perfect for this.
Each heap entry will track:
val: the numberarrIdx: which array it came fromelemIdx: its position in that arrayThis guarantees sorted order. Do this until the heap is empty.
function mergeKSortedArrays(arrays) { const result = []; const minHeap = []; // Atom 2: Seed the heap with the first element of each array for (let arrIdx = 0; arrIdx < arrays.length; arrIdx++) { if (arrays[arrIdx].length > 0) { minHeap.push({ val: arrays[arrIdx][0], arrIdx, elemIdx: 0 }); } } // Atom 1: Heapify by sorting (for simplicity, not efficient) minHeap.sort((a, b) => a.val - b.val); // Atom 3: Main loop while (minHeap.length > 0) { // Remove the smallest element const { val, arrIdx, elemIdx } = minHeap.shift(); result.push(val); // Push the next element from the same array, if any const nextIdx = elemIdx + 1; if (nextIdx < arrays[arrIdx].length) { minHeap.push({ val: arrays[arrIdx][nextIdx], arrIdx, elemIdx: nextIdx }); // Maintain heap property minHeap.sort((a, b) => a.val - b.val); } } return result; }
mergeKSortedArrays([ [1, 4, 9], [2, 5, 8], [0, 6, 7] ]); // โ [0, 1, 2, 4, 5, 6, 7, 8, 9]
O(log k)nO(n log k)Can be optimized with a real heap (
MinPriorityQueueor custom binary heap) instead of.sort().
Let's do a step-by-step dry run of mergeKSortedArrays using this example:
const arrays = [ [1, 4, 9], [2, 5, 8], [0, 6, 7] ];
Goal: Merge into one sorted array.
We push the first element of each array into the heap:
minHeap = [ { val: 1, arrIdx: 0, elemIdx: 0 }, { val: 2, arrIdx: 1, elemIdx: 0 }, { val: 0, arrIdx: 2, elemIdx: 0 } ]
Then we sort it:
minHeap = [ { val: 0, arrIdx: 2, elemIdx: 0 }, { val: 1, arrIdx: 0, elemIdx: 0 }, { val: 2, arrIdx: 1, elemIdx: 0 } ]
0 โ result = [0]6{ val: 6, arrIdx: 2, elemIdx: 1 }[1, 2, 6] โ after sort:minHeap = [ { val: 1, arrIdx: 0, elemIdx: 0 }, { val: 2, arrIdx: 1, elemIdx: 0 }, { val: 6, arrIdx: 2, elemIdx: 1 } ]
1 โ result = [0, 1]4{ val: 4, arrIdx: 0, elemIdx: 1 }[2, 6, 4] โ sort:minHeap = [ { val: 2, arrIdx: 1, elemIdx: 0 }, { val: 4, arrIdx: 0, elemIdx: 1 }, { val: 6, arrIdx: 2, elemIdx: 1 } ]
2 โ result = [0, 1, 2]5{ val: 5, arrIdx: 1, elemIdx: 1 }[4, 6, 5] โ sort:minHeap = [ { val: 4, arrIdx: 0, elemIdx: 1 }, { val: 5, arrIdx: 1, elemIdx: 1 }, { val: 6, arrIdx: 2, elemIdx: 1 } ]
4 โ result = [0, 1, 2, 4]9{ val: 9, arrIdx: 0, elemIdx: 2 }[5, 6, 9] โ sort:minHeap = [ { val: 5, arrIdx: 1, elemIdx: 1 }, { val: 6, arrIdx: 2, elemIdx: 1 }, { val: 9, arrIdx: 0, elemIdx: 2 } ]
5 โ result = [0, 1, 2, 4, 5]8{ val: 8, arrIdx: 1, elemIdx: 2 }[6, 9, 8] โ sort:minHeap = [ { val: 6, arrIdx: 2, elemIdx: 1 }, { val: 8, arrIdx: 1, elemIdx: 2 }, { val: 9, arrIdx: 0, elemIdx: 2 } ]
6 โ result = [0, 1, 2, 4, 5, 6]7{ val: 7, arrIdx: 2, elemIdx: 2 }[8, 9, 7] โ sort:minHeap = [ { val: 7, arrIdx: 2, elemIdx: 2 }, { val: 8, arrIdx: 1, elemIdx: 2 }, { val: 9, arrIdx: 0, elemIdx: 2 } ]
7 โ result = [0, 1, 2, 4, 5, 6, 7]8 โ result = [0, 1, 2, 4, 5, 6, 7, 8]9 โ result = [0, 1, 2, 4, 5, 6, 7, 8, 9][0, 1, 2, 4, 5, 6, 7, 8, 9]
Test your understanding with 3 quick questions