Problem
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 O(log (m+n))
.
Examples
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.
Median Definition
Simpler version of problem - Median of Two Sorted Array of Equal or Same Size.
Method 1 - Brute Force by Merging 2 Arrays and Keeping Count
We can combine two arrays until we locate the middle one or two elements, but this requires O(n) space and time.
Method 2 - Binary Search with getKth Element
This problem can be transformed into finding the kth element, where k is (length of A + length of B)/2.
If either array is empty, the kth element is simply the kth element of the non-empty array. When k is 0, the kth element is the first element of either A or B.
In typical scenarios, we adjust the pointer to discard half of A and B recursively by comparing their medians:
if (aMid < bMid) Keep [aRight + bLeft]
else Keep [bRight + aLeft]
Time complexity - O (log(n+m))
To find the median, calculate the total array length. Let m
be the length of num1
and n
be the length of nums2
. The total length, len
, determines the approach:
- For an odd total length (e.g., num1 is 6 and nums2 is 7), the median is the 7th element, i.e.,
len/2 + 1
. - For an even total length (e.g., both m and n are 6), the median is the average of the 6th and 7th elements, i.e.,
len/2
andlen/2 + 1
.
Code
Java
public double findMedianSortedArrays(int[] nums1, int[] nums2) {
int m = nums1.length;
int n = nums2.length;
int len = m + n;
if(len % 2 == 0){
double left = (double)findKthHelper(nums1, 0, nums2, 0, len/2);
double right = (double)findKthHelper(nums1, 0, nums2, 0, len/2 + 1);
return (double)(left + right)/2;
}else{
return findKthHelper(nums1, 0, nums2, 0, len/2 + 1);
}
}
private int findKthHelper(int[] A, int aStart, int[] B, int bStart, int k){
// If nums1 is exhausted, return kth number in nums2
if(aStart >= A.length){
return B[bStart + k - 1];
}
// If nums2 is exhausted, return kth number in nums1
if(bStart >= B.length){
return A[aStart + k - 1];
}
// Since nums1 and nums2 is sorted, the smaller one among the start point of nums1 and nums2 is the first one
if(k == 1){
return Math.min(A[aStart], B[bStart]);
}
int aMid = aStart + k/2 - 1;
int bMid = bStart + k/2 - 1;
int aVal = aMid >= A.length ? Integer.MAX_VALUE : A[aMid];
int bVal = bMid >= B.length ? Integer.MAX_VALUE : B[bMid];
// Throw away half of the array from nums1 or nums2. And cut k in half
if(aVal <= bVal){
return findKthHelper(A, aMid + 1, B, bStart, k - k/2);
}else{
return findKthHelper(A, aStart, B, bMid + 1, k - k/2);
}
}
Complexity
- ⏰ Time complexity:
O(log (min(m,n)))
wherem
andn
is length of 2 input arrays. The primary function,findMedianSortedArrays
, callsfindKthHelper
either once or twice, each with a time complexity ofO(log(min(m, n)))
. - The binary search infindKthHelper
reduces the search space by half each time it is called, leading toO(log(min(m, n)))
in each call. - 🧺 Space complexity:
O(log (min(m,n)))
, as we use recursion stack.
Method 3 - Iterative with Edge Case Handling
Code
Java
public double findMedianSortedArrays(int[] nums1, int[] nums2) {
int l1 = 0;
int l2 = 0;
int med1 = 0;
int med2 = 0;
int totalLength = nums1.length + nums2.length;
for (int i=0; i<= totalLength/2; i++) {
med1 = med2;
// If all elements of nums1 are already considered
if (l1 == nums1.length) {
med2 = nums2[l2];
l2++;
// If all elements of nums2 are already considered
} else if (l2 == nums2.length) {
med2 = nums1[l1];
l1++;
// If element in nums1 is smaller than element in nums2
} else if (nums1[l1] < nums2[l2] ) {
med2 = nums1[l1];
l1++;
// If element in nums2 is smaller than element in nums1
} else {
med2 = nums2[l2];
l2++;
}
}
// if totalLength is even, median is the average of the two middle elements
if (totalLength % 2 == 0) {
return (float)(med1+med2)/2;
}
// if totalLength is odd, median is the middle element
return med2;
}
Complexity
- ⏰ Time complexity:
O(m + n)
, asi
iterates from0
to(m + n) / 2
. - 🧺 Space complexity:
O(1)