🧠
Optimal Approach (Binary Search on Partition)
💡 This approach uses binary search to partition the arrays so that the left halves contain the median elements, achieving O(log(min(m,n))) time.
Intuition
Partition the two arrays such that all elements on the left are less than or equal to those on the right, then compute median from partition edges.
Algorithm
- Ensure nums1 is the smaller array to minimize binary search range.
- Set binary search boundaries on nums1 indices.
- While searching, partition nums1 and nums2 such that left partitions have half the total elements.
- Check if partition is valid: max left ≤ min right for both arrays.
- If valid, compute median from max left and min right elements.
- Else adjust binary search boundaries accordingly.
💡 The challenge is correctly defining partitions and handling edge cases when partitions are at array boundaries.
def findMedianSortedArrays(nums1, nums2):
if len(nums1) > len(nums2):
nums1, nums2 = nums2, nums1
m, n = len(nums1), len(nums2)
low, high = 0, m
half_len = (m + n + 1) // 2
while low <= high:
i = (low + high) // 2
j = half_len - i
max_left_nums1 = float('-inf') if i == 0 else nums1[i - 1]
min_right_nums1 = float('inf') if i == m else nums1[i]
max_left_nums2 = float('-inf') if j == 0 else nums2[j - 1]
min_right_nums2 = float('inf') if j == n else nums2[j]
if max_left_nums1 <= min_right_nums2 and max_left_nums2 <= min_right_nums1:
if (m + n) % 2 == 1:
return float(max(max_left_nums1, max_left_nums2))
else:
return (max(max_left_nums1, max_left_nums2) + min(min_right_nums1, min_right_nums2)) / 2.0
elif max_left_nums1 > min_right_nums2:
high = i - 1
else:
low = i + 1
# Driver code
if __name__ == '__main__':
print(findMedianSortedArrays([1,3], [2])) # 2.0
print(findMedianSortedArrays([1,2], [3,4])) # 2.5
Line Notes
if len(nums1) > len(nums2):Ensure binary search is on smaller array for efficiency
half_len = (m + n + 1) // 2Calculate half length for partitioning
max_left_nums1 = float('-inf') if i == 0 else nums1[i - 1]Handle edge case when partition is at start
if max_left_nums1 <= min_right_nums2 and max_left_nums2 <= min_right_nums1:Check if partition is valid
public class Solution {
public static double findMedianSortedArrays(int[] nums1, int[] nums2) {
if (nums1.length > nums2.length) return findMedianSortedArrays(nums2, nums1);
int m = nums1.length, n = nums2.length;
int low = 0, high = m;
int halfLen = (m + n + 1) / 2;
while (low <= high) {
int i = (low + high) / 2;
int j = halfLen - i;
int maxLeftNums1 = (i == 0) ? Integer.MIN_VALUE : nums1[i - 1];
int minRightNums1 = (i == m) ? Integer.MAX_VALUE : nums1[i];
int maxLeftNums2 = (j == 0) ? Integer.MIN_VALUE : nums2[j - 1];
int minRightNums2 = (j == n) ? Integer.MAX_VALUE : nums2[j];
if (maxLeftNums1 <= minRightNums2 && maxLeftNums2 <= minRightNums1) {
if ((m + n) % 2 == 1) {
return Math.max(maxLeftNums1, maxLeftNums2);
} else {
return (Math.max(maxLeftNums1, maxLeftNums2) + Math.min(minRightNums1, minRightNums2)) / 2.0;
}
} else if (maxLeftNums1 > minRightNums2) {
high = i - 1;
} else {
low = i + 1;
}
}
throw new IllegalArgumentException("Input arrays are not sorted");
}
public static void main(String[] args) {
System.out.println(findMedianSortedArrays(new int[]{1,3}, new int[]{2})); // 2.0
System.out.println(findMedianSortedArrays(new int[]{1,2}, new int[]{3,4})); // 2.5
}
}
Line Notes
if (nums1.length > nums2.length)Swap arrays to binary search smaller one
int halfLen = (m + n + 1) / 2;Calculate half length for partitioning
int maxLeftNums1 = (i == 0) ? Integer.MIN_VALUE : nums1[i - 1];Handle partition at start of nums1
if (maxLeftNums1 <= minRightNums2 && maxLeftNums2 <= minRightNums1)Check if partition is valid
#include <iostream>
#include <vector>
#include <climits>
using namespace std;
double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) {
if (nums1.size() > nums2.size()) return findMedianSortedArrays(nums2, nums1);
int m = nums1.size(), n = nums2.size();
int low = 0, high = m;
int halfLen = (m + n + 1) / 2;
while (low <= high) {
int i = (low + high) / 2;
int j = halfLen - i;
int maxLeftNums1 = (i == 0) ? INT_MIN : nums1[i - 1];
int minRightNums1 = (i == m) ? INT_MAX : nums1[i];
int maxLeftNums2 = (j == 0) ? INT_MIN : nums2[j - 1];
int minRightNums2 = (j == n) ? INT_MAX : nums2[j];
if (maxLeftNums1 <= minRightNums2 && maxLeftNums2 <= minRightNums1) {
if ((m + n) % 2 == 1) return (double)max(maxLeftNums1, maxLeftNums2);
return (max(maxLeftNums1, maxLeftNums2) + min(minRightNums1, minRightNums2)) / 2.0;
} else if (maxLeftNums1 > minRightNums2) {
high = i - 1;
} else {
low = i + 1;
}
}
throw invalid_argument("Input arrays are not sorted");
}
int main() {
vector<int> a1 = {1,3};
vector<int> a2 = {2};
cout << findMedianSortedArrays(a1, a2) << endl; // 2.0
vector<int> b1 = {1,2};
vector<int> b2 = {3,4};
cout << findMedianSortedArrays(b1, b2) << endl; // 2.5
return 0;
}
Line Notes
if (nums1.size() > nums2.size())Swap arrays to ensure binary search on smaller array
int halfLen = (m + n + 1) / 2;Calculate half length for partitioning
int maxLeftNums1 = (i == 0) ? INT_MIN : nums1[i - 1];Handle partition at start of nums1
if (maxLeftNums1 <= minRightNums2 && maxLeftNums2 <= minRightNums1)Check if partition is valid
function findMedianSortedArrays(nums1, nums2) {
if (nums1.length > nums2.length) return findMedianSortedArrays(nums2, nums1);
let m = nums1.length, n = nums2.length;
let low = 0, high = m;
let halfLen = Math.floor((m + n + 1) / 2);
while (low <= high) {
let i = Math.floor((low + high) / 2);
let j = halfLen - i;
let maxLeftNums1 = (i === 0) ? -Infinity : nums1[i - 1];
let minRightNums1 = (i === m) ? Infinity : nums1[i];
let maxLeftNums2 = (j === 0) ? -Infinity : nums2[j - 1];
let minRightNums2 = (j === n) ? Infinity : nums2[j];
if (maxLeftNums1 <= minRightNums2 && maxLeftNums2 <= minRightNums1) {
if ((m + n) % 2 === 1) {
return Math.max(maxLeftNums1, maxLeftNums2);
} else {
return (Math.max(maxLeftNums1, maxLeftNums2) + Math.min(minRightNums1, minRightNums2)) / 2;
}
} else if (maxLeftNums1 > minRightNums2) {
high = i - 1;
} else {
low = i + 1;
}
}
throw new Error("Input arrays are not sorted");
}
console.log(findMedianSortedArrays([1,3], [2])); // 2.0
console.log(findMedianSortedArrays([1,2], [3,4])); // 2.5
Line Notes
if (nums1.length > nums2.length)Swap arrays to binary search smaller one
let halfLen = Math.floor((m + n + 1) / 2);Calculate half length for partitioning
let maxLeftNums1 = (i === 0) ? -Infinity : nums1[i - 1];Handle partition at start of nums1
if (maxLeftNums1 <= minRightNums2 && maxLeftNums2 <= minRightNums1)Check if partition is valid
TimeO(log(min(m, n)))
SpaceO(1)
Binary search is performed on the smaller array, reducing the search space logarithmically.
💡 For arrays of size 100,000, this means about 17 operations (log2 100,000), which is extremely efficient.
Interview Verdict: Accepted and optimal solution
This is the best approach to implement in interviews for this problem due to its efficiency and elegance.