Median of Two Sorted Arrays hard
Problem Statement
There are two sorted arrays nums1
and nums2
of size m
and n
respectively. Find the median of the two sorted arrays. The overall run time complexity should be O(log (m+n)).
Example 1
nums1 = [1, 3]
nums2 = [2]
The median is 2.0
Example 2
nums1 = [1, 2]
nums2 = [3, 4]
The median is (2 + 3)/2 = 2.5
Steps
The core idea is to use binary search to find a partition point in the smaller array that allows us to efficiently find the median. Here's a breakdown of the steps:
-
Ensure
nums1
is the smaller array: Swapnums1
andnums2
ifnums1
is longer thannums2
. This simplifies the logic. -
Binary Search: Perform a binary search on
nums1
. The goal is to find a partitionpartitionX
innums1
such that the number of elements to the left ofpartitionX
innums1
plus the number of elements to the left of a corresponding partitionpartitionY
innums2
equals(m+n)/2
. -
Calculate
partitionY
:partitionY
is determined by the equation:partitionY = (m + n + 1) / 2 - partitionX
(The+1
handles cases with an odd total number of elements). -
Find maxLeft and minRight: After finding
partitionX
andpartitionY
, identifymaxLeft
(the maximum of the left partitions) andminRight
(the minimum of the right partitions). These are crucial for determining the median. -
Calculate the Median: If
m + n
is even, the median is the average ofmaxLeft
andminRight
. Otherwise, it's justmaxLeft
(orminRight
, as they'll be equal).
Explanation
The binary search cleverly avoids explicitly merging the arrays. By carefully choosing the partition points, we can find the median using just the partition values. The correctness relies on the fact that we have two sorted arrays – the partitioning ensures we've considered elements from both arrays that would be present in the sorted merged array.
Code
class Solution {
public double findMedianSortedArrays(int[] nums1, int[] nums2) {
int m = nums1.length;
int n = nums2.length;
// Ensure nums1 is the smaller array
if (m > n) {
int[] temp = nums1;
nums1 = nums2;
nums2 = temp;
int tempLen = m;
m = n;
n = tempLen;
}
int low = 0, high = m;
while (low <= high) {
int partitionX = (low + high) / 2;
int partitionY = (m + n + 1) / 2 - partitionX;
int maxLeftX = (partitionX == 0) ? Integer.MIN_VALUE : nums1[partitionX - 1];
int minRightX = (partitionX == m) ? Integer.MAX_VALUE : nums1[partitionX];
int maxLeftY = (partitionY == 0) ? Integer.MIN_VALUE : nums2[partitionY - 1];
int minRightY = (partitionY == n) ? Integer.MAX_VALUE : nums2[partitionY];
if (maxLeftX <= minRightY && maxLeftY <= minRightX) {
if ((m + n) % 2 == 0) {
return (double) (Math.max(maxLeftX, maxLeftY) + Math.min(minRightX, minRightY)) / 2;
} else {
return (double) Math.max(maxLeftX, maxLeftY);
}
} else if (maxLeftX > minRightY) {
high = partitionX - 1;
} else {
low = partitionX + 1;
}
}
throw new IllegalArgumentException("Arrays are not sorted."); // Should never reach here if inputs are valid.
}
}
Complexity
- Time Complexity: O(log(min(m, n))) due to the binary search on the smaller array.
- Space Complexity: O(1). The algorithm uses constant extra space.