Given two sorted arrays of integers, merge them into one sorted array containing all numbers
Example:
Input: first =[1, 4, 8], second = [1, 3, 4, 17] Output: [1, 1, 3, 4, 4, 8, 17]
Your algorithm should run in O(n + m) time and use O(n + m) extra space.
The core challenge of this problem is to merge two already sorted arrays into a single sorted array efficiently. This problem is significant in various applications such as merging data from different sources, combining search results, and more. A common pitfall is to use a naive approach that doesn't take advantage of the fact that the input arrays are already sorted.
To solve this problem, we can use a two-pointer technique. This approach leverages the fact that both arrays are already sorted, allowing us to merge them in linear time.
A naive solution would be to concatenate the two arrays and then sort the resulting array. However, this approach is not optimal as it has a time complexity of O((n + m) log(n + m)) due to the sorting step.
The optimized solution involves using two pointers to traverse both arrays and compare their elements. We initialize two pointers, one for each array, and iterate through both arrays, adding the smaller element to the result array and moving the corresponding pointer forward. This ensures that we maintain the sorted order in the result array.
Here is a step-by-step breakdown of the optimized algorithm:
function mergeSortedArrays(first, second) {
// Initialize pointers for both arrays
let i = 0;
let j = 0;
// Initialize the result array
let result = [];
// Traverse both arrays
while (i < first.length && j < second.length) {
// Compare elements at the current pointers
if (first[i] < second[j]) {
// Add the smaller element to the result array
result.push(first[i]);
// Move the pointer of the first array
i++;
} else {
// Add the smaller element to the result array
result.push(second[j]);
// Move the pointer of the second array
j++;
}
}
// Add remaining elements of the first array, if any
while (i < first.length) {
result.push(first[i]);
i++;
}
// Add remaining elements of the second array, if any
while (j < second.length) {
result.push(second[j]);
j++;
}
return result;
}
// Example usage
const first = [1, 4, 8];
const second = [1, 3, 4, 17];
console.log(mergeSortedArrays(first, second)); // Output: [1, 1, 3, 4, 4, 8, 17]
The time complexity of this algorithm is O(n + m), where n and m are the lengths of the two input arrays. This is because we traverse each array exactly once. The space complexity is also O(n + m) due to the result array that stores all elements from both input arrays.
Potential edge cases include:
Our algorithm handles these edge cases effectively by ensuring that all elements are added to the result array in sorted order.
To test the solution comprehensively, consider the following test cases:
mergeSortedArrays([], [])
should return []
.mergeSortedArrays([1, 2, 3], [])
should return [1, 2, 3]
.mergeSortedArrays([1, 2, 2], [2, 3, 4])
should return [1, 2, 2, 2, 3, 4]
.mergeSortedArrays([1], [2, 3, 4, 5])
should return [1, 2, 3, 4, 5]
.When approaching such problems, consider the following tips:
In this blog post, we discussed how to merge two sorted arrays efficiently using a two-pointer technique. We covered the problem definition, approach, algorithm, code implementation, complexity analysis, edge cases, and testing. Understanding and solving such problems is crucial for improving problem-solving skills and preparing for technical interviews.
For further reading and practice, consider the following resources: