Median of Two Sorted Arrays
Table of contents
Problem
Given two sorted arrays nums1
and nums2
of size m
and n
respectively, return the median of the two sorted arrays.
Input: nums1 = [1,3], nums2 = [2]
Output: 2.00000
Explanation: merged array = [1,2,3] and median is 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.
Explanation
Let
Let’s assume that
Let
This
where
For
andIf
is odd, then .If
is even, then
Let
The first condition can be rewritten as:
The notation follows the coding convention of 0-based indexing.
The second condition can be rewritten as:
Later in code, the integer division truncating (m + n + 1) / 2
takes care of both odd and even cases.
We see that
Once we find the right
Why
for odd ?Because we know the left side has one more element which is the median.
Why
for even ?Because we want the average of the two middle elements.
Now we do a binary search on
Solution
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
public double findMedianSortedArrays(int[] A, int[] B) {
int m = A.length;
int n = B.length;
// Because we want to do a binary search on the smaller array
if (m > n) return findMedianSortedArrays(B, A);
// Setting candidate range for i
int iMin = 0;
int iMax = m;
int lenCondition = (m + n + 1) / 2;
while (iMin <= iMax) {
int i = (iMin + iMax) / 2;
int j = lenCondition - i;
int maxALeft = (i < 1) ? Integer.MIN_VALUE : A[i - 1];
int maxBLeft = (j < 1) ? Integer.MIN_VALUE : B[j - 1];
int minARight = (i >= m) ? Integer.MAX_VALUE : A[i];
int minBRight = (j >= n) ? Integer.MAX_VALUE : B[j];
if (maxALeft <= minBRight && maxBLeft <= minARight) {
if ((m + n) % 2 > 0) { // When m + n is odd,
return Math.max(maxALeft, maxBLeft); // Median is at the left
} else { // When m + n is even,
// Median is the average of the two middle elements
return (Math.max(maxALeft, maxBLeft) + Math.min(minARight, minBRight)) / 2.0;
}
} else if (maxALeft > minBRight) { // We overshot our partition for A
iMax = i - 1;
} else { // We undershot our partition for A
iMin = i + 1;
}
}
return 0.0;
}
Everything is explained in the Explanation section, except for the lines 17-20.
maxALeft
:maxBLeft
:minARight
:minBRight
:
We must note that a partition of
Take
We want
That is why we need to turn them into
By setting
The complexity is