01
Problem Statement
Given two sorted arrays nums1 and nums2 of size m and n, return the median of the two sorted arrays. The overall run time should be O(log (m+n)). If the merged array has an odd length, the median is the middle element; if even, it is the average of the two middle elements.
- We cannot merge the arrays (that would be O(m+n)). We use a partition idea: imagine a partition that splits the merged sorted array into a left half and a right half of equal (or nearly equal) size. The median is determined by the elements around that partition.
02
Key Observations
- Partition approach: We want the left half of the merged array to have
(m+n+1)/2elements. Partitionnums1at indexi(left partnums1[0..i-1], rightnums1[i..m-1]) andnums2at indexjso thati + j = (m+n+1)/2. The left half hasmax(nums1[i-1], nums2[j-1])as its max; the right half hasmin(nums1[i], nums2[j])as its min. For a valid partition we needmaxLeft1 <= minRight2andmaxLeft2 <= minRight1. Binary search oni(in the smaller array) and computej; adjustlo/hibased on the comparison. Median =(maxLeft + minRight) / 2or justmaxLeftif total length is odd.
03
Approach
High-level: Ensure nums1 is the shorter array. Binary search on i (cut in nums1). j = (m+n+1)/2 - i. Check maxLeft1 <= minRight2 and maxLeft2 <= minRight1. If maxLeft1 > minRight2, i is too large (hi = i - 1); if maxLeft2 > minRight1, i is too small (lo = i + 1). When valid, median = (max(maxLeft1, maxLeft2) + min(minRight1, minRight2)) / 2 (or just max(maxLeft1, maxLeft2) if total length odd).
Steps:
- If
nums1.length > nums2.length, swap so we binary search on the smaller array.m = nums1.length,n = nums2.length,half = (m+n+1)/2. lo = 0,hi = m. Whilelo <= hi:i = (lo+hi)/2,j = half - i. GetmaxLeft1,minRight1,maxLeft2,minRight2(use -inf/+inf at boundaries). IfmaxLeft1 <= minRight2 && maxLeft2 <= minRight1, compute and return median. Else ifmaxLeft1 > minRight2,hi = i - 1; elselo = i + 1.- Return median value.
04
Implementation
Java
public double findMedianSortedArrays(int[] nums1, int[] nums2) {
if (nums1.length > nums2.length) {
return findMedianSortedArrays(nums2, nums1);
}
int m = nums1.length, n = nums2.length;
int lo = 0, hi = m;
while (lo <= hi) {
int i = (lo + hi) / 2, j = (m + n + 1) / 2 - i;
int maxL1 = i == 0 ? Integer.MIN_VALUE : nums1[i-1];
int minR1 = i == m ? Integer.MAX_VALUE : nums1[i];
int maxL2 = j == 0 ? Integer.MIN_VALUE : nums2[j-1];
int minR2 = j == n ? Integer.MAX_VALUE : nums2[j];
if (maxL1 <= minR2 && maxL2 <= minR1) {
if ((m+n) % 2 == 0) {
return (Math.max(maxL1, maxL2) + Math.min(minR1, minR2)) / 2.0;
}
return Math.max(maxL1, maxL2);
}
if (maxL1 > minR2) {
hi = i - 1;
}
else {
lo = i + 1;
}
}
return 0;
}05
Test Cases
Example 1
Input
nums1 = [1,3], nums2 = [2]
Expected
2.0Explanation
Merged [1,2,3], median 2.
06
Complexity Analysis
- Time: O(log(min(m,n))).
- Space: O(1).
07
Follow-ups
- K-th element of two sorted arrays (generalize).