题目
There are two sorted arrays nums1 and nums2 of size m and n respectively.
Find the median of the two sorted arrays.
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
题解
这道题是求出两个有序数组的中位数。一个很容易想到的方法是,用两个指针分别指向这两个数组的开头,并且哪个指针指向的数字小则向前移动,移动到(m+n)/2的位置时即为中位数,时间复杂度为O(m+n)。
题目要求是O(log(m+n))的时间复杂度,然而用这个方法竟然也能过了,说明OJ还不是很严格。
另外想到的方法是用类似求出数组第K大的数字的分治思想。
代码1
class Solution {
boolean which = false;
int a, b;
public double findMedianSortedArrays(int[] nums1, int[] nums2) {
if(nums1.length == 0){
return median(nums2);
}
if(nums2.length == 0){
return median(nums1);
}
int i = 0, j = 0;
int n = nums1.length + nums2.length;
final boolean even = (n & 1) != 1;
while (true){
if(i + j >= n / 2 + 1){
if(even){
return ((double) a + b)/2;
}else {
return Math.max(a, b);
}
}
if(j >= nums2.length || (i < nums1.length && nums1[i] < nums2[j])){
if(which){
a = nums1[i];
}else {
b = nums1[i];
}
i++;
}else {
if(which){
a = nums2[j];
}else {
b = nums2[j];
}
j++;
}
which = !which;
}
}
private double median(int[] nums) {
int n = nums.length / 2;
if((nums.length & 1) == 1){
return nums[n];
}
return ((double) nums[n - 1] + nums[n])/2;
}
}
代码2
class Solution {
public:
double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) {
int n = nums1.size();
int m = nums2.size();
if(n > m) //保证数组1一定最短
return findMedianSortedArrays(nums2,nums1);
int L1,L2,R1,R2,c1,c2,lo = 0, hi = 2*n; //我们目前是虚拟加了'#'所以数组1是2*n长度
while(lo <= hi) //二分
{
c1 = (lo+hi)/2; //c1是二分的结果
c2 = m+n- c1;
L1 = (c1 == 0)?INT_MIN:nums1[(c1-1)/2]; //map to original element
R1 = (c1 == 2*n)?INT_MAX:nums1[c1/2];
L2 = (c2 == 0)?INT_MIN:nums2[(c2-1)/2];
R2 = (c2 == 2*m)?INT_MAX:nums2[c2/2];
if(L1 > R2)
hi = c1-1;
else if(L2 > R1)
lo = c1+1;
else
break;
}
return (max(L1,L2)+ min(R1,R2))/2.0;
}
};