Walk both arrays with two pointers until reaching the middle position(s).
Approach 1
class Solution {
public double findMedianSortedArrays(int[] a, int[] b) {
int total = a.length + b.length, i = 0, j = 0, prev = 0, cur = 0;
for (int k = 0; k <= total / 2; k++) {
prev = cur;
if (i < a.length && (j >= b.length || a[i] <= b[j])) cur = a[i++];
else cur = b[j++];
}
return total % 2 == 1 ? cur : (prev + cur) / 2.0;
}
}
Verdict: Simple; misses the logarithmic requirement.
2
Optimal: binary search the partition
Time O(log(min(m, n))) Space O(1)
Search i in 0..m on the smaller array a; j = half − i. Use −∞/+∞ for elements beyond the ends. If a[i−1] > b[j], move i left; if b[j−1] > a[i], move i right. When balanced, the median comes from the max of the left sides and min of the right sides.
Approach 2
class Solution {
public double findMedianSortedArrays(int[] a, int[] b) {
if (a.length > b.length) return findMedianSortedArrays(b, a);
int m = a.length, n = b.length, half = (m + n + 1) / 2;
int lo = 0, hi = m;
while (lo <= hi) {
int i = (lo + hi) / 2, j = half - i;
int aLeft = i == 0 ? Integer.MIN_VALUE : a[i - 1];
int aRight = i == m ? Integer.MAX_VALUE : a[i];
int bLeft = j == 0 ? Integer.MIN_VALUE : b[j - 1];
int bRight = j == n ? Integer.MAX_VALUE : b[j];
if (aLeft > bRight) hi = i - 1;
else if (bLeft > aRight) lo = i + 1;
else {
int leftMax = Math.max(aLeft, bLeft);
if ((m + n) % 2 == 1) return leftMax;
return (leftMax + (double) Math.min(aRight, bRight)) / 2.0;
}
}
throw new IllegalArgumentException("arrays not sorted");
}
}
Verdict: The classic hard binary search.
Before you submit
Edge cases and common mistakes
Test these inputs
One array empty
All of a smaller than all of b
Odd and even totals
Mistakes people make
Searching on the longer array (j can go out of range).
Integer division when averaging the two middle values.
Interview
Follow-up questions
How would you find the kth smallest of two sorted arrays?