理解“两个排序数组的中位数”算法

时间:2012-09-25 14:04:22

标签: algorithm

  

有两个分别为大小为m和n的排序数组A和B.找   两个排序数组的中位数。整体运行时复杂性   应为O(log(m + n))。

double findMedianSortedArrays(int A[], int m, int B[], int n) {
    return findMedianHelper2(A, m, B, n, max(0, (m-n)/2), min(m-1, (m+n)/2));
}

double findMedianHelper2(const int A[], const int m, const int B[], const int n, const int l, const int r) {
    if (l > r) return findMedianHelper2(B, n, A, m, max(0, (n-m)/2), min(n-1, (m+n)/2));

    int i = (l+r)/2;
    int j = (m+n)/2-i;

    assert(i >= 0 && i <= m && j >= 0 && j <= n);
    int Ai_1 = ((i == 0) ? INT_MIN : A[i-1]);
    int Bj_1 = ((j == 0) ? INT_MIN : B[j-1]);
    int Ai = ((i == m) ? INT_MAX : A[i]);
    int Bj = ((j == n) ? INT_MAX : B[j]);

    if (Ai < Bj_1) return findMedianHelper2(A, m, B, n, i+1, r);
    if (Ai > Bj) return findMedianHelper2(A, m, B, n, l, i-1);

    if (((m+n) % 2) == 1) return A[i];
    return (max(Ai_1, Bj_1) + Ai) / 2.0;
}

问题:选择l = max(0, (m-n)/2)r = min(m-1, (m+n)/2)

的含义是什么

谢谢

5 个答案:

答案 0 :(得分:1)

这段代码对我来说没有意义。但是,我认为这里的关键是确保m> n并且值(m-n)/ 2和(m + n)/ 2正确地传递给辅助函数。 另外,从辅助函数开头的if语句中,我们可以看到当m&lt; n。

时,目的是解决问题。

假设m> 0且n> 0(它们必须是这样才能使数组有意义。)

如果m> n,那么在帮助器内,(l&gt; r)将为假,算法应该运行良好。
如果m

因此,我认为代码在开始时有问题。
然而,主要部分似乎对我有意义,并确实帮助我实现在JAVA中做同样的事情。

答案 1 :(得分:0)

问题&gt;选择l = max(0,(m-n)/ 2)和r = min(m-1,(m + n)/ 2)

是什么意思

MAX和MIN用于钳制值,使它们不能低于或高于约束条件。

IF m - n < 0 THEN
    l = 0
ELSE l = (m - n) / 2

IF (m + n) / 2 > m - 1 THEN
    r = m -1
ELSE r = (m + n) / 2

答案 2 :(得分:0)

首先。让我们证明m = n情况下的算法。 将中间元素命名为“k”

  • M1:= A [N / 2]

    M2:= B [N / 1]`

    如果m1&lt; m2,所以m1&lt; k&lt; m2否则m2&lt; k&lt; M1。

    证明:m1&lt; k so so m2&lt;但是它不正确:“k”元素指数明显高于n。因此,m2&gt; ķ。

如果m1> k与我们的平均值相同。 ķ。

  • A和B合并的中间元素将是A / 2和B / 2以相同的方式合并中间元素。 所以我们需要继续在两个数组中找到元素:A / 2和B / 2,所以转到1)项直到数组变得相等。

答案 3 :(得分:0)

答案 4 :(得分:0)

选择这样的左右索引的原因是跳过不能是两个排序数组的中值的元素。

不失一般性,我们假设m > n。然后有两个边缘情况:

  • 即使B中的所有元素都小于A[0],由于A[0, ... , (m - n) / 2 - 1],中位数仍然不可能是n + (m - n) / 2 - 1 < (m + n) / 2中的元素。
  • 同样,即使B中的所有元素都大于A [m - 1],中位数仍然不可能是A[(m + n) / 2 + 1, ... , m - 1]中的元素,因为A[(m + n) / 2]必须是中位数。< / LI>

基于这种观察,我们只需要在较长数组的子阵列上执行二进制搜索,以便找到中位数。

m < nl = max(0, (m-n)/2) = 0r = min(m-1, (m+n)/2) = m - 1的情况下,这实际上意味着中位数可能是较短数组中的任何元素。