【两个有序数组求中位数】

来源:互联网 发布:淘宝手机抢购 编辑:程序博客网 时间:2024/06/13 12:22
/*
两个有序数组求中位数问题;
这个题有很多方法:
方法一:排序,找到中位数;
方法二:归并排序的思想
方法三:转换成求第k小值  
*/


/*
思路:使用二分查找,时间复杂度为log(m+n). 该方法的核心是将原问题转变成
一个寻找第k小数的问题(假设两个原序列升序排列),
这样中位数实际上是第(m+n)/2小的数。所以只要解决了第k小数的 问题,
原问题也得以解决。首先假设数组A和B的元素个数都大于k/2,
我们比较A[k/2-1]和B[k/2-1]两个元素,这两个元素分别表示A的第k /2小的元素
和B的第k/2小的元素。这两个元素比较共有三种情况:>、<和=。
如果A[k/2-1]<B[k/2-1],这表示 A[0]到A[k/2-1]的元素都在A和B合并之后的前k小的元素中。
换句话说,A[k/2-1]不可能大于两数组合并之后的第k小值,所以我们可以将 其抛弃。
*/
#include<iostream>


using namespace std;


double findKth(int a[], int m, int b[], int n, int k)
{
if (m>n)
{
return findKth(b,n,a,m,k);
}


if (m==0)
{
return b[k-1];
}
if (k==1)
{
return min(a[0], b[0]);
}


int pa = min(k/2, m);
int pb = k - pa;
if (a[pa-1]<b[pb-1])
{
return findKth(a+pa, m-pa, b,  n, k-pa);
}
else if (a[pa-1]>b[pb-1])
{
return findKth(a, m, b+pb, n-pb, k-pb);
}
else
{
return a[pa-1];
}
}


class Solution
{
double findMedian(int A[], int m, int B[], int n)
{
int total = m + n;
if (total&0x1)
{
return findKth(A, m, B, n, total/2+1);
}
else
{
return (findKth(A, m, B, n, total / 2) + findKth(A,m,B,n,total/2+1))/2;
}
}
};
原创粉丝点击