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
给出两个排列好的数组,找出这两个数组组合起来的元素的中值
思路:
所有元素扫描一遍找中值的话时间复杂度是O(m+n),而题中要求O(log(m+n)),考虑到binary search
假如总长度是n,那么中值应该在n/2的位置(n是奇数时)
这个n/2位置的前半部分由nums1的m1个元素,nums2的m2个元素组成,所以只要知道了m1,就能知道m2 ( m2 = n/2 - m1)
所以现在的目标是找到m1
假如
nums1 = [ 1, 2, | 5, 6 ]
nums2 = [ 3, 4, | 7, 8 ]
nums = [1, 2, 3 , 4 | 5, 6, 7, 8]
先取m1为nums1的中点,m1取2, 那么m2=2
因为是排好序的,最大元素在最右边
nums1和nums2的前半段最后一个元素中较大的,是合并数组nums的前半段中值。
后半段第一个元素中较小的,是nums的后半段中值。
nums2前半段最后一个元素nums2[m2-1] < nums1后半段第一个元素nums1[m1]
如果nums1[m1] < nums2[m2-1]就说明nums1的分段要更靠后,left = m1+1
否则right = m1, 就是用binary search找到合适的分段点m1
时间复杂度是O(log(min(m, n)))
//2ms
public double findMedianSortedArrays(int[] nums1, int[] nums2) {
if (nums1.length > nums2.length) {
return findMedianSortedArrays(nums2, nums1);
}
int n1 = nums1.length;
int n2 = nums2.length;
int left = 0;
int right = n1; //if =n1-1, then if only 1 element, won't go loop
int k = (n1 + n2 + 1) / 2;
int m1 = 0;
int m2 = 0;
//get m1 elements from nums1..
while (left < right) {
m1 = left + (right - left) / 2;
m2 = k - m1;
if (nums1[m1] < nums2[m2 - 1]) {
left = m1 + 1;
} else {
right = m1;
}
}
m1 = left;
m2 = k - m1;
int c1 = Math.max((m1 <= 0) ? Integer.MIN_VALUE : nums1[m1 - 1],
(m2 <= 0) ? Integer.MIN_VALUE : nums2[m2 - 1]);
int c2 = Math.min((m1 >= n1) ? Integer.MAX_VALUE : nums1[m1],
(m2 >= n2) ? Integer.MAX_VALUE : nums2[m2]);
if ((n1 + n2) % 2 == 1) {
return c1;
} else {
return (c1 + c2) / 2.0;
}
}