n个对象的等价性测试

时间:2014-10-02 09:21:13

标签: algorithm recursion divide-and-conquer

假设我们被给予' n'对象和一个子程序,它接受两个输入并说明它们是否相等(例如,如果它们相等,它可以将输出设为1)。

我需要提出一种算法,该算法调用上述函数O(n log n)次,并确定输入是否超过' n / 2'彼此相同的项目。

4 个答案:

答案 0 :(得分:4)

您可以使用Boyer-Moore多数投票算法,该算法最多可进行n-1次比较。

function find_majority(A)
    majority = None
    count = 0
    for a in A:
        if count == 0
            majority = a
        else if a == majority
            count += 1
        else
            count -= 1
    return majority

如果在数组中出现的次数超过n / 2次,则返回最常见的元素。

如果你需要知道是否是一个多数项,那么你可以再次通过数组计算从find_majority函数返回的值出现的次数。这增加了另外n个比较。

答案 1 :(得分:3)

这是一个经典的分而治之的解决方案,它给出了O(n log n)

分为两个子集,A1和A2,...,并且显示T(n)是O(n log n)。 如果A具有多数元素v,则v也必须是A1或A2或两者的多数元素。该 等效的反对重述是立即的:(如果v <=每个的一半,则<=总数的一半。)如果两个部分具有相同的多数元素,则它自动成为A的主要元素。如果一个部分中有多数元素,计算两个部分中元素的重复次数(在O(n)时间内),看它是否是多数元素。如果两个部分都占多数,则可能需要对两个候选者中的每一个进行此计数,仍为O(n)。这种分裂可以递归地完成。基本情况是当n = 1时。递归关系是T(n)= 2T(n / 2)+ O(n),因此T(n)是主定理的O(n log n)。

http://anh.cs.luc.edu/363/handouts/MajorityProblem.pdf

答案 2 :(得分:0)

Paul Hankin的答案是$\mathcal{O}(n)$解决方案,非常花哨。

如果不使用Boyer-Moore,我们也可以在$\mathcal{O}(nlogn)$中解决此问题。每次比较之后,我们将“不同”的牌对“丢弃”,并将相等的对“合并”到组中,依此类推,每次我们丢弃相同数量的卡,最后剩下的牌或卡组就是“多数” ”,那么我们可以再次进行比较以检查卡是否为True。

每当我们掉落时,我们至少会掉落一张多数卡和另一张,因此不会影响结果,掉落的过程是“抵消”操作。无论丢弃或合并,都可以帮助我们减少至少一半的卡。因此,递归时间为$logn$,总时间为$nlogn$

答案 3 :(得分:-3)

考虑到序列是有序的,您可以使用binary search,这需要O(log n),因为您必须为每个元素执行此操作,并且您拥有n元素拿O(n*log n)