使用O(log n)查询从n个条目的数据库中提取中值

时间:2016-10-18 11:04:05

标签: algorithm

假设我有两个数据库,每个数据库包含n条目。将中位数定义为n&#39最小值。我们可以通过查询从给定的数据库中一次提取一个值。

Query(k)返回k指定数据库的最小值。如何使用最多O(log n)次查询找到中位数?

2 个答案:

答案 0 :(得分:2)

所需的时间复杂度为n,表明我们应该尝试找到二元搜索方法。与二分搜索类似但略有不同,我们仍然每次将// As Query(k) will return k'th smallest element, considering database as container of sorted entries for understanding purpose. E.g., DB1 = [1, 3, 5, 7, 9] DB2 = [2, 4, 6, 8, 10]. n = 5. i = n / 2 = 2; j = n - i = 3; i DB1 [1, 3, 5, 7, 9] j DB2[2, 4, 6, 8, 10] 分成两半。

DB1.Query(i) < DB2.Query(j)

如果1,则表示iDB1中包含n的元素必须存在于第一个(n - i)元素中。

现在,下一步是找到n / 2中的DB1(等于i + 1)元素(从nDB2)和{{ 1}}(从1n)。这个程序可以被视为&#34;切割&#34;来自一个数据库的n / 2个元素,并继续从另一个数据库和&#34; new&#34;中找到其他n / 2个元素。切割后的数据库。

如果DB1.Query(i) > DB2.Query(j),则应用相同的程序,但我们会切断&#34; DB2数据库。

通过这种方式,我们每次都有&#34; cut&#34;来自其中一个数据库的n / 2个元素,下一次是从该数据库中删除(n / 2) / 2个元素,直到:

  • n = 1DB1.Query(1)DB2.Query(1)中较小的一个是&#34; nth元素&#34;。
  • 其中一个数据库结束了。然后只返回其他数据库中的当前n元素。

我假设DB1DB2是两个数据库的数据库处理程序。这种语法类似于C ++,但你可以理解。这可确保O(log n)复杂性。

// Find k'th smallest element of the two combind database entries
int findMedianofDatabaseHelper(DBHandler* db1, int i, DBHandler* db2, int j, const int n, int k) {
    if((n - i) > (n - j))
    {
        return findMedianofDatabaseHelper(db2, j, db1, i, n, k);
    }
    if(i >= n)
    {
        return db2->Query(j + k);
    }
    if(j >= n)
    {
        return db1->Query(i + k);
    }
    if(k == 1)
    {
        return min(db1->Query(i + 1), db2->Query(j + 1));
    }

    int aMid = min(k / 2, n - i);
    int bMid = k - aMid;

    if(db1->Query(i + aMid) <= db2->Query(j + bMid))
    {
        return findMedianofDatabaseHelper(db1, i + aMid, db2, j, n, k - aMid);
    }

    return findMedianofDatabaseHelper(db1, i, db2, j + bMid, n, k - bMid);
}

// assuming DBHandler is a wrapper of database handler/instance on which we can perform query
int findMedianofDatabase(DBHandler* db1, DBHandler* db2, int n)
{
    return findMedianofDatabaseHelper(db1, 0, db2, 0, n, n);
}

Here我用C ++模拟了工作程序。

答案 1 :(得分:0)

你基本上可以通过二分搜索找到它(如果n不是2的幂,则可以进行一些调整):查询两个数据库中的n/2 - 最小元素m1, m2。如果他们是平等的,那么你有中位数。如果是m1<m2,则要求3n/4 - 第一个最小,1/4 - 第二个最小,反之亦然m1>m2。重复。

在每个步骤中,您所选元素的元素数量与上面相同。