![](/img/trans.png)
[英]Why does my O(NLogN) algorithm to find anagrams run faster than my O(N) algorithm?
[英]select algorithm to find element occurring more than n/2 in O(n)
不使用摩尔算法或哈希表,我需要找到在数组中出现超过n/2
次的元素。
我知道我必须使用中位数中值的选择算法。 关于什么选择算法返回我很困惑,因为如果它返回中位数我怎么确定元素在数组中出现超过n/2
次?
例如:
a [] = {4,1,5,7,8}
5是中位数但不超过n/2
次。
现在:
a [] = {5,5,3,4,5,5}
在这种情况下,中位数是5,并且它发生超过n/2
次。
我想建议另一种方法。 这个问题被称为“寻找领导者”(至少在波兰文学中)。 让我们称一个元素的出现次数超过序列前导的n/2
倍。 以下观察是至关重要的 - 如果序列中存在领导者,则在移除两个不同元素之后,新创建的序列将具有与原始序列完全相同的领导者。 这是为什么? 如果有一个领导者,在删除两个不同的元素后,其中只有一个是领导者。 新序列具有n - 2
元素,并且超过原始领导者的(n / 2) - 1
出现,因此最初的领导者是新的领导者。 重复删除,直到所有元素相等。 然后,如果候选人是领导者,您可以执行线性检查。
示例代码(基于这篇文章 ,很遗憾没有英文版):
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");
使用select算法查找中值元素。 在这里,如果元素超过n / 2次,很明显它是中位数。 使用中位数中位数来获得O(n)的运行时间。 一旦得到中间元素,只计算它在数组中的出现次数,这也是线性时间
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.