Median of Two Sorted Arrays

来源:互联网 发布:周杰伦英雄 知乎 编辑:程序博客网 时间:2024/06/06 06:52

1.题目

两个排序的数组A和B分别含有m和n个数,找到两个排序数组的中位数,要求时间复杂度应为O(log (m+n))。

2.算法

问题等价于求两个array的第k=(m+n)/2(假设m和n分别是两个数组的元素个数)大的数是多少,基本思路是每次递归查看两数组第k/2大的数(设为a[k/2],b[k/2])如果a[k/2]>b[k/2],那么说明b的前k/2大元素都不是我们要找的数,如果a[k/2]<b[k/2],那么说明a的前k/2大元素都不是我们要找的数,我们把他舍去,同时由于我们舍去了要找的前k小元素的一写元素,k的值在下次递归中要变小,如果a[k/2]=b[k/2],说明当前这个数即为两个数组剩余元素的第k大的数最终k=1时即为结果。此题还有一些边界条件,如下

1、如果A或者B为空,则直接返回B[k-1]或者A[k-1]

2、如果k为1,我们只需要返回A[0]和B[0]中的较小值

3、如果A[k/2]=B[k/2],返回其中一个

4、有时候剩下的数不足k/2个,那么就得剩下的,而另一个数组则需要多取一些数

    public double findMedianSortedArrays(int[] a, int[] b) {    if ((a.length + b.length) % 2 == 1)     {   //如果为奇数,找中间的数        return helper(a, b, 0, a.length - 1, 0, b.length - 1, (a.length + b.length) / 2 + 1);    }    else     {  //如果偶数,找中间两数,除以2        return (helper(a, b, 0, a.length - 1, 0, b.length - 1, (a.length + b.length) / 2)        + helper(a, b, 0, a.length - 1, 0, b.length - 1, (a.length + b.length) / 2 + 1)) / 2.0;    }    }    public double helper(int[] a, int[] b, int i, int i2, int j, int j2, int k)    {        int m = i2 - i + 1;        int n = j2 - j + 1;        if (m > n) //我们假设第一的数组,要找到元素较小        {            return helper(b, a, j, j2, i, i2, k);        }        if (m == 0)        {            return b[j + k - 1]; //如果A或者B为空,则直接返回B[k-1]或者A[k-1]        }        if (k == 1) // 如果k为1,我们只需要返回A[0]和B[0]中的较小值        {            return Math.min(a[i], b[j]);        }        // 有时候剩下的数不足k/2个,那么就得剩下的,而另一个数组则需要多取一些数        int posA = Math.min(k / 2, m);        int posB = k - posA;        if (a[posA + i - 1] < b[j + posB - 1])         {            return helper(a, b, i + posA, i2, j, j + posB - 1, k - posA);        }        else        {            return helper(a, b, i, i + posA - 1, j + posB, j2, k - posB);        }    }

在最好情况下,每次都有k一半的元素被删除,所以算法复杂度为logk,由于求中位数时k为(m+n)/2,所以算法复杂度为log(m+n)。

python

    def findMedianSortedArrays(self, A, B):        # write your code here        n = len(A) + len(B)        if n % 2 == 1:            return self.findKth(A, B, n / 2 + 1)        else:            return (self.findKth(A, B, n / 2) +             self.findKth(A, B, n / 2 + 1))/2.0                    def findKth(self, A, B, k):        if len(A) == 0:            return B[k - 1]        if len(B) == 0:            return A[k - 1]        if k == 1:            return min(A[0], B[0])        a = A[k/2 - 1] if len(A) >= k/2 else None        b = B[k/2 - 1] if len(B) >= k/2 else None        if b is None or (a is not None and a < b):            return self.findKth(A[k/2:], B, k - k/2)        return self.findKth(A, B[k/2:], k - k/2)


0 0
原创粉丝点击