Apply binary search on the smaller array to find a partition point such that all elements on the left side are less than or equal to all elements on the right side. This achieves O(log(min(M, N))) time complexity.
class Solution:
def findMedianSortedArrays(self, nums1: list[int], nums2: list[int]) -> float:
A, B = nums1, nums2
total = len(nums1) + len(nums2)
half = total // 2
if len(B) < len(A):
A, B = B, A
l, r = 0, len(A) - 1
while True:
i = (l + r) // 2 # A
j = half - i - 2 # B
Aleft = A[i] if i >= 0 else float("-inf")
Aright = A[i + 1] if (i + 1) < len(A) else float("inf")
Bleft = B[j] if j >= 0 else float("-inf")
Bright = B[j + 1] if (j + 1) < len(B) else float("inf")
if Aleft <= Bright and Bleft <= Aright:
if total % 2:
return min(Aright, Bright)
return (max(Aleft, Bleft) + min(Aright, Bright)) / 2
elif Aleft > Bright:
r = i - 1
else:
l = i + 1
class Solution {
public double findMedianSortedArrays(int[] nums1, int[] nums2) {
if (nums1.length > nums2.length) {
return findMedianSortedArrays(nums2, nums1);
}
int m = nums1.length, n = nums2.length;
int left = 0, right = m;
while (left <= right) {
int i = (left + right) / 2;
int j = (m + n + 1) / 2 - i;
int maxLeftA = (i == 0) ? Integer.MIN_VALUE : nums1[i - 1];
int minRightA = (i == m) ? Integer.MAX_VALUE : nums1[i];
int maxLeftB = (j == 0) ? Integer.MIN_VALUE : nums2[j - 1];
int minRightB = (j == n) ? Integer.MAX_VALUE : nums2[j];
if (maxLeftA <= minRightB && maxLeftB <= minRightA) {
if ((m + n) % 2 == 0) {
return (Math.max(maxLeftA, maxLeftB) + Math.min(minRightA, minRightB)) / 2.0;
} else {
return Math.max(maxLeftA, maxLeftB);
}
} else if (maxLeftA > minRightB) {
right = i - 1;
} else {
left = i + 1;
}
}
return 0.0;
}
}