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)).
- You may assume nums1 and nums2 cannot be both empty.
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
Solution: Binary Search
- 要找
median
,原始的方法是把两个arrays合并,然后找中位数。但是Time Complexity
是O(m + n)
- 那么
O(log (m+n))
的要求,就肯定是binary search, 思路如下
class Solution {
public double findMedianSortedArrays(int[] nums1, int[] nums2) {
//1. Binary search: to find partition x & partition Y, such that
//
// 1) partition x + partition y = (xLen + yLen + 1) / 2, means element number of left half == element number of right half
// 2) all elements from two arrays left half <= all elements from two arrays right half
// x1, x2,| x3, x4, x5, x6,
// y1, y2, y3, y4, y5,| y6, y7, y8
// partition x = 2, partition y = 5 ==> left half has 5 elements, right half has 5 elements
// and make sure x2 <= y6 && y5 <=x3 (coz it's sorted array, therefore already guaranteed x2 <= x3, y5 <= y6)
if (nums1.length > nums2.length) {
return findMedianSortedArrays (nums2, nums1);
}
int nums1Len = nums1.length;
int nums2Len = nums2.length;
int halfLen = (nums1Len + nums2Len + 1) / 2;
int start = 0;
int end = nums1Len;
int partitionX = 0;
int partitionY = 0;
while (start <= end) {
partitionX = start + (end - start) / 2;
partitionY = halfLen - partitionX;
// if partitionX == 0, means there is nothing on the left, use MIN_VALUE instead
int maxLeftX = partitionX == 0 ? Integer.MIN_VALUE : nums1 [partitionX - 1];
int maxLeftY = partitionY == 0 ? Integer.MIN_VALUE : nums2 [partitionY - 1];
// if partitionX == nums1 Len, means there is nothing on the right, use MAX_VALUE instead
int minRightX = partitionX == nums1Len ? Integer.MAX_VALUE : nums1 [partitionX];
int minRightY = partitionY == nums2Len ? Integer.MAX_VALUE : nums2 [partitionY];
if (maxLeftX <= minRightY && maxLeftY <= minRightX) {
// if combined array len is even
if ((nums1Len + nums2Len) % 2 == 0) {
//System.out.println ("1+++++" + "x: " + partitionX + " Y: " + partitionY);
return (Math.max (maxLeftX, maxLeftY) + Math.min (minRightX, minRightY)) / 2.0;
}
// if it's odd
//System.out.println ("2+++++" + "x: " + partitionX + " Y: " + partitionY);
return (Math.max (maxLeftX, maxLeftY));
} else if (maxLeftX > minRightY) {
end = partitionX - 1;
} else if (maxLeftY > minRightX) {
start = partitionX + 1;
}
}
return -1;
}
}