不使用Moore的算法或哈希表,我需要找到在数组中出现超过n/2
次的元素。
我知道我必须使用中位数中位数的选择算法。我对选择算法的返回方式感到困惑,因为如果它返回中位数我怎么确定元素在数组中出现的时间超过n/2
次?
例如:
a [] = {4,1,5,7,8}
5是中位数,但不会超过n/2
次。
现在:
a [] = {5,5,3,4,5,5}
在这种情况下,中位数为5,发生次数超过n/2
次。
答案 0 :(得分:2)
我想建议另一种方法。这个问题被称为“寻找领导者”(至少在波兰文学中)。让我们调用一个元素,该元素的出现次数是序列前导的n/2
倍。以下观察是至关重要的 - 如果序列中存在领导者,则在删除两个不同的元素之后,新创建的序列将具有与原始序列完全相同的领导者。这是为什么?如果有一个领导者,在删除两个不同的元素后,其中只有一个是领导者。新序列具有n - 2
个元素,并且超过(n / 2) - 1
原始领导者的出现,因此原始领导者是新的领导者。重复删除,直到所有元素相等。然后,如果候选人是领导者,您可以执行线性检查。
示例代码(基于this article,很遗憾无法用英语提供):
int leader = 0;
int number = 0; /* number of occurences of a leader candidate */
for (int k = 0; k < n; k++)
{
if (number == 0)
{
//we set first element as a potential leader
leader = a[k];
number = 1;
}
else if (leader == a[k])
//new leader occurence
number++;
else
//delete two different elements
number--;
}
//check if it really is the leader
number = 0;
for (int i = 0; i < n; i++)
if (a[i] == leader)
number++;
if (number > n / 2)
System.out.println(leader);
else
System.out.println("There is no leader");
答案 1 :(得分:1)
使用select算法查找中间元素。在这里,如果元素超过n / 2次,很明显它是中位数。使用中位数中位数来获得O(n)的运行时间。一旦得到中值元素,只计算它在数组中的出现次数,这也是线性时间