题目描述:
分析:
思路一:思路就是从两个数组不断找较小者,找到第n个就返回。
class Solution {
public:
/**
* find median in two sorted array
* @param arr1 int整型vector the array1
* @param arr2 int整型vector the array2
* @return int整型
*/
int findMedianinTwoSortedAray(vector<int>& arr1, vector<int>& arr2) {
// write code here
int l = 0, r = 0;
int res = 0;
while(l + r < arr1.size()){
if(arr2[r] < arr1[l])
res = arr2[r++];
else
res = arr1[l++];
}
return res;
}
};
思路二:二分arr1,可以得到对应的arr2(保证arr1的前i个和arr2的前j个刚好凑够N个)
class Solution {
public:
/**
* find median in two sorted array
* @param arr1 int整型vector the array1
* @param arr2 int整型vector the array2
* @return int整型
*/
int findMedianinTwoSortedAray(vector<int>& arr1, vector<int>& arr2) {
// write code here
int N = arr1.size();
int l = 0, r = N-1;
int res = 0;
while(l <= r){
int mid = (l+r)>>1;
if(mid == N-1)
return min(arr1[N-1], arr2[0]);
if(arr1[mid] == arr2[N-mid-2])
return arr1[mid];
if(arr1[mid] < arr2[N-mid-2]){
l = mid+1;
}
else
r = mid-1;
}
if(r < 0)
return min(arr1[0], arr2[N-1]);
int a = max(arr1[l], arr2[N-2-l]);
int b = max(arr1[r], arr2[N-2-r]);
return min(a, b);
}
};
思路三:
看到时间复杂度为O(logN),很容易想到二分查找。过程如下:
如果每个数组中只有一个元素,较小的那个元素就是整体的上中位数,如果两个元素相等,随便返回哪个都可以。
如果数组中不止一个元素,找到两个数组的中间位置mid1和mid2。
如果arr1[mid1] == arr2[mid2],不管每个数组中元素的个数是奇数还是偶数,这两个数都可以是整体的上中位数,返回其中一个就可以。
如果arr1[mid1] > arr2[mid2],每个数组的个数是奇数的情况下:数组arr1中mid1位置以后的数都不可能是整体的上中位数,数组arr2中mid2位置以前的数都不可能是整体的上中位数。所以现在只需要考虑arr1[left1…mid1]、arr2[mid2…right],这两部分的元素个数相同,它们的上中位数就是整体的上中位数。
如果arr1[mid1] > arr2[mid2],每个数组的个数是偶数的情况下:数组arr1中mid1位置以后的数都不可能是整体的上中位数,数组arr2中mid2位置以后包括mid2位置,都不可能是整体的上中位数。所以现在只需要考虑arr1[left1…mid1]、arr2[mid2+1…right],这两部分的元素个数相同,它们的上中位数就是整体的上中位数。
arr1[mid1] < arr2[mid2]的情况,分析同上。
class Solution {
public:
/**
* find median in two sorted array
* @param arr1 int整型vector the array1
* @param arr2 int整型vector the array2
* @return int整型
*/
//由时间复杂度,想到二分查找
int findMedianinTwoSortedAray(vector<int>& arr1, vector<int>& arr2) {
// write code here
int n = arr1.size();
if(n==0){
return NULL;
}
//arr1左右两端
int l1=0,r1=n-1;
//arr2左右两端
int l2=0,r2=n-1;
int mid1,mid2;
//终止条件为l1=r1,即两个数组都只有一个元素,此时的上中位数为两数的最小值
while(l1< r1){
//arr1中位数
mid1 = l1+((r1-l1)>>1);
//arr2中位数
mid2 = l2+((r2-l2)>>1);
int k = r1-l1+1;
if(arr1[mid1] == arr2[mid2]){ //若两数组中位数相等,整体中位数也是这个
return arr1[mid1];
}
else if(arr1[mid1] > arr2[mid2]){
if(k%2 == 0){//区间元素个数为偶数
r1 = mid1; //整体中位数在arr1左区间,包括mid1
l2 = mid2+1; //整体中位数在arr2右区间,不包括mid2
}
else if(k%2 == 1){ //区间元素个数为奇数
r1 = mid1; //整体中位数在arr1左区间,包括mid1
l2 = mid2; //整体中位数在arr2右区间,包括mid2
}
}
else if (arr1[mid1] < arr2[mid2]){
if(k%2 == 0){//区间元素个数为偶数
r2 = mid2; //整体中位数在arr2左区间,包括mid2
l1 = mid1+1; //整体中位数在arr1右区间,不包括mid1
}
else if(k%2 == 1){ //区间元素个数为奇数
r2 = mid2; //整体中位数在arr2左区间,包括mid2
l1 = mid1; //整体中位数在arr1右区间,包括mid1
}
}
}
//当区间内只有一个元素时,两个区间中最小值即为整体中位数
return min(arr1[l1],arr2[l2]);
}
};