Median of Two Sorted Arrays
π― Difficulty: HARD
π LeetCodeProblem Statement
Given two sorted arrays nums1 and nums2 of size m and n respectively, return the median of the two sorted arrays.
The overall run time complexity should be .
Example 1:
Input: nums1 = [1,3], nums2 = [2]
Output: 2.00000
Explanation: merged array = [1,2,3] and median is 2.
Example 2:
Input: nums1 = [1,2], nums2 = [3,4]
Output: 2.50000
Explanation: merged array = [1,2,3,4] and median is (2 + 3) / 2 = 2.5.
Approach: Binary Search on the Smaller Array
Finding the median of two sorted arrays is equivalent to partitioning both arrays into a single left half and a single right half such that:
- Both halves have an equal number of elements (or the left half has one more if the total number of elements is odd).
- Every element in the left half is less than or equal to every element in the right half.
Instead of merging the arrays, we can run a Binary Search on the smaller array to find the correct partition point. By ensuring we binary search on the smaller array, we guarantee time complexity.
- Let
Abe the smaller array andBbe the larger array (swapnums1andnums2ifnums1.length > nums2.length). - Let be the length of
Aand be the length ofB. The total number of elements in the left half is . - We set our binary search bounds on
A:left = 0andright = m. - While
left <= right, we calculate the partition indexiinA:i = Math.floor((left + right) / 2)- The partition index
jinBis forced to be:j = half - i.
- We look at the elements directly on the left and right of these partitions:
Aleft: The largest element on the left side ofA(use ifi === 0).Aright: The smallest element on the right side ofA(use ifi === m).Bleft: The largest element on the left side ofB(use ifj === 0).Bright: The smallest element on the right side ofB(use ifj === n).
- Check if the partition is valid. Itβs valid if all elements on the left are all elements on the right. This means
Aleft <= BrightandBleft <= Aright.- If valid:
- If the total number of elements is odd, the median is
Math.max(Aleft, Bleft). - If the total number of elements is even, the median is
(Math.max(Aleft, Bleft) + Math.min(Aright, Bright)) / 2.
- If the total number of elements is odd, the median is
- If invalid:
- If
Aleft > Bright, we have too many elements fromAon the left. We must move our partitionito the left:right = i - 1. - Otherwise,
Bleft > Aright. We need more elements fromAon the left:left = i + 1.
- If
- If valid:
Solution
/**
* @param {number[]} nums1
* @param {number[]} nums2
* @return {number}
*/
function findMedianSortedArrays(nums1, nums2) {
let A = nums1;
let B = nums2;
// Always run binary search on the smaller array to guarantee O(log(min(m, n)))
if (A.length > B.length) {
let temp = A;
A = B;
B = temp;
}
const m = A.length;
const n = B.length;
let left = 0;
let right = m;
const half = Math.floor((m + n + 1) / 2);
while (left <= right) {
const i = Math.floor((left + right) / 2); // partition in A
const j = half - i; // partition in B
const Aleft = i === 0 ? -Infinity : A[i - 1];
const Aright = i === m ? Infinity : A[i];
const Bleft = j === 0 ? -Infinity : B[j - 1];
const Bright = j === n ? Infinity : B[j];
// Partition is correct
if (Aleft <= Bright && Bleft <= Aright) {
// Odd total length
if ((m + n) % 2 !== 0) {
return Math.max(Aleft, Bleft);
}
// Even total length
return (Math.max(Aleft, Bleft) + Math.min(Aright, Bright)) / 2.0;
}
// Aleft is too big, partition in A must move left
else if (Aleft > Bright) {
right = i - 1;
}
// Aright is too small, partition in A must move right
else {
left = i + 1;
}
}
return 0; // Should never reach here if inputs are valid arrays
}
Complexity Analysis
- Time Complexity: where and are the lengths of the two arrays. By swapping the arrays to ensure we always perform binary search on the smaller array, the search space is at most .
- Space Complexity: . We are only using a few pointers and variables to keep track of indices and bounds, requiring constant extra space.