Median of Two Sorted Arrays

来源:互联网 发布:windows命令ftp放文件 编辑:程序博客网 时间:2024/06/06 14:07

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)).


问题原本很简单,在两个已排序过的字符串中找到第K大的数。这本来就是在归并里的merge步骤嘛,一步一步往前走,然后排序之后找到其索引。时间复杂度是merge的复杂度:O(M+N)

但是这狗日的问题要求让你在时间复杂度O(logM+logN)中找到。最开始直接让我懵逼了。想了好久,才想明白怎么做。其实所谓的log时间复杂度,都是log2为底的对数。看到这里,学数学出身的我们应该对这个很敏感,就是说每次以2的指数形式减少,翻译过来就是说——每次要减少一半规模!


所以这个问题翻译过来之后,指定了这样的时间复杂度,实际上也就暗暗地给你指明了道路了。每次的算法,要筛选掉一半的数据。照着这个提示继续往下走吧!


继续想:在a中M个排序的和b中N个已排序的找第K大的数。那么我可以先求一下a和b的中位数mida,midb,之后看一眼,它们的和


一个小trick:如何判断我这个数是奇数还是偶数


用1和这个数做&运算。如果这个数是奇数,就执行if语句,如果是偶数,则执行else语句。

代码:两种方式筛选。一种是筛选用不到的数据,一种是筛选用到的数据。

筛选用不到的:

判断a[mid_a] 与 b[mid_b]的关系
 如果a[mida] < b[mid_b]

 1)k小于等于mida + midb + 1,那么b数组从mid_b开始就没有用了,缩小b的搜索范围
 2)k大于mida + midb + 1, 那么a数组从low到mid_a开始就没用了,缩小a的搜索范围
 3)终止条件是 a搜索完 返回b中元素或者相反

<span style="font-family:Helvetica Neue, Helvetica, Arial, sans-serif;color:#333333;">int get_k_from_sorted_array2(int* a, int*b, int la, int ha, int lb, int hb, int k){    if(la > ha)        return b[lb + k - 1];    if(lb > hb)        return a[la + k - 1];    int mida = (la + ha)>>1;    int midb = (lb + hb)>>1;    int num = mida- la + midb - lb + 1;    cout<<la<<" "<<ha<<" "<<lb<<" "<<hb<<" "<<num<<" "<<a[mida]<<" "<<b[midb]<<endl;        if(a[mida] <= b[midb])    {        if(k <= num)            return get_k_from_sorted_array2(a, b, la, ha, lb, midb - 1, k);        else            return get_k_from_sorted_array2(a, b, mida + 1, ha, lb, hb, k - (mida - la + 1));    }    else    {        if(k <= num)            return get_k_from_sorted_array2(a, b, la, mida - 1, lb, hb, k);        else            return get_k_from_sorted_array2(a, b, la, ha, midb + 1, hb, k - (midb - lb + 1));    }}int _func2(int* a, int a_len, int* b, int b_len, int k){    int rst = 0;    if(a_len + b_len < k)        return -1;    int p1 = a_len > k ? k : a_len;    int p2 = b_len > k ? k : b_len;    cout<<p1<<" "<<p2<<endl;    rst = get_k_from_sorted_array2(a, b, 0, p1 - 1, 0, p2 - 1, k);    return rst;}</span>

筛选能用到的数据:

假设A数组中取第x个数,Y数组取第y个数,并且满足x+y=K,若A[x] < B[y],则比A[x]小的数必然小于K个,也就是说A[1]~A[x]都比第K小的数要小,可以舍弃掉然后求第K-x小的数;若A[x] > B[y]也是一样的道理。
class Solution:    # @return a float    def findMedianSortedArrays(self, A, B):        totlen = len(A) + len(B)        if (1 & totlen):            return self.findK(A, B, (totlen + 1) / 2)        else:            return (self.findK(A, B, totlen / 2) + self.findK(A, B, totlen / 2 + 1)) / 2.0            def findK(self, A, B, K):        la, lb, pa, pb = len(A), len(B), min(K/2, len(A)), K - min(K/2, len(A))        if (la > lb):            return self.findK(B, A, K)        if (la == 0):            return B[K-1]        if (K == 1):            return min(A[0], B[0])        if A[pa - 1] < B[pb - 1]:            return self.findK(A[pa:], B, K - pa)        elif A[pa - 1] > B[pb - 1]:            return self.findK(A, B[pb:], K- pb)        else:            return A[pa - 1]


1 0
原创粉丝点击