确定线性时间内是否存在多数元素

时间:2013-11-05 20:19:21

标签: algorithm computer-science

这是我的面试问题,我有点难过。给定k个元素的阵列设计用于确定列表是否具有多数元素的线性时间算法,其中多数元素是在列表中出现多于k / 2次的元素。

4 个答案:

答案 0 :(得分:4)

您可以使用O(n)时间内运行的Boyer's algorithm。它通过阵列两次。

该算法对多数元素使用初始candidate值,并将计数器count初始设置为零。

第一遍看起来像这样:

int count = 0;
T candidate = null;
foreach (var element in array) {
    if (count == 0) {
        candidate = element;
        count = 1;
    } else {
        if (candidate == element) {
            count++;
        } else {
            count--;
        }
    }
}

如果存在多数元素,candidate将在循环结束时等于它。但是,如果没有多数元素,候选人可能包含误报。第二遍考虑到了:

count = 0;
foreach (var element in array) {
    if (element == candidate) {
        count++;
    }
}
if (count > array.Length/2) {
    Console.WriteLine("Majority element is {0}", candidate);
} else {
    Console.WriteLine("No majority element");
}

答案 1 :(得分:2)

您可以将数组的元素散列为整数值,其中元素的值是散列的键,散列的值是数组中每个元素的出现次数的计数。您还可以将最大出现次数存储为最大值;如果最大值> k / 2,该列表具有多数元素,您甚至不需要再次遍历哈希。

答案 2 :(得分:1)

Robert S Boyer和J Strother Moore编写了一种算法,该算法在O(n)时间和O(1)空间中找到大部分,并且可以在线使用,例如存储在磁带上的数据(假设单个倒带)。这个想法是始终保持候选赢家,每次看到候选人时将计数递增1,每次看到其他候选人时将计数递减1,并且每当计数为零时用当前项重置候选人。如果存在多数,则幸存的候选人占多数;这需要单独传递数据,计算候选人的出现次数。 Boyer和Moore(编写字符串匹配算法的人)编写了一个令人愉快的paper,它不仅描述了算法,还描述了他们的FORTRAN 77程序的正式证明。我在my blog的Scheme中有一个实现。

答案 3 :(得分:0)

Create Hashmap, with elements as keys and counters as values
For each item
   If the item doesn't have an entry in the hashmap,
       Create a counter, starting with a zero value

   Increment the counter stored in the hashmap
   If the count > k /2
       Then this element is the majority element; return true

There is no max if we reach this line; return false