您的位置:首页 > 其它

LeetCode刷题-寻找两个有序数组的中位数

2019-03-12 09:47 417 查看

寻找两个有序数组的中位数

题目

给定两个大小为 m 和 n 的有序数组 nums1 和 nums2。

请你找出这两个有序数组的中位数,并且要求算法的时间复杂度为 O(log(m + n))。

你可以假设 nums1 和 nums2 不会同时为空。

样例

  1. nums1 = [1, 3]
    nums2 = [2]
    则中位数是 2.0
  2. nums1 = [1, 2]
    nums2 = [3, 4]
    则中位数是 (2 + 3)/2 = 2.5

Code

分析
通过两个数组元素总数(total)与十六进制1(0x1)进行按位与计算,判断total是奇数还是偶数。
假设A和B的元素个数都大雨k/2,将A的第k/2个元素(即A[k/2-1])和B的第k/2个元素(即B[k/2-1])进行比较:

  • A[k/2-1]==B[k/2-1]
  • A[k/2-1] > B[k/2-1]
  • A[k/2-1] < B[k/2-1]

如果A[k/2-1] < B[k/2-1],则A[0]到A[k/2-1]的元素肯定在TOPk元素范围内,可以删除A中的前k/2个元素;
如果A[k/2-1] > B[k/2-1],则B[0]到B[k/2-1]的元素肯定在TOPk元素范围内,可以删除B中的前k/2个元素;
如果A[k/2-1] == B[k/2-1],则找到第k大的元素,直接返回A[k/2-1]或B[k/2-1];
采用递归函数查找第k大的元素,会有三种终止条件:

  • 当A或B为空时,直接返回B[k-1]或A[k-1];
  • 当k==1时,返回min(A[0], B[0]);
  • 当A[k/2-1] == B[k/2-1],返回A[k/2-1]或B[k/2-1]。

时间复杂度O(log(m+n)),空间复杂度O(log(m+n))

double findMedianSortedArrays(vector<int>& A, vector<int>& B) {
const int m=A.size();
const int n=B.size();
int total=m+n;
if(total & 0x1) {
return find_kth(A.begin(), m, B.begin(), n, total/2+1);
} else {
return (find_kth(A.begin(), m, B.begin(), n, total/2)+find_kth(A.begin(), m, B.begin(), n, total/2+1))/2.0;
}
}

static int find_kth(std::vector<int>::const_iterator A,int m,std::vector<int>::const_iterator B,int n,int k) {
if(m>n) {
return find_kth(B,n,A,m,k);
}
if(m==0) {
return *(B+k-1);
}
if(k==1) {
return min(*A,*B);
}
int ia=min(k/2,m),ib=k-ia;
if(*(A+ia-1)<*(B+ib-1)) {
return find_kth(A+ia,m-ia,B,n,k-ia);
} else if(*(A+ia-1)>*(B+ib-1)) {
return find_kth(A,m,B+ib,n-ib,k-ib);
} else {
return A[ia-1];
}
}

若有疑问欢迎评论!

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: