因此,对于一项任务,我们要求找到写一个伪代码,对于给定的序列,从序列中找到一个数字的最大频率。所以,一个简单的例子是:
[1,8,5,6,6,7,6,7,6,1,1,5,8] =>频率最高的数字是6."获胜者"是6。
我们必须在O(nlogm)时间内实现它,其中m是不同数字的数量。因此,在上面的例子中,有5个不同的数字(m = 5)。
我的方法是遍历序列中的每个数字并将其添加到二叉树(如果尚未存在)并增加频率。因此,对于序列中的每个数字编号,我的程序进入二叉树,找到元素(以logm时间)并将频率增加1。它会记录n次,因此程序在O(nlogm)中运行。但是,要找出具有最大频率的数字将需要另一个O(m)。我留下了O(nlogm + m),删掉了低阶词,这留下了O(m),这不是教授所要求的。
我从课堂上记得,为了在根处保留最频繁的访问项目,使用splay树是一个很好的选择,因此最多给我O(1)或O(logn)来让我"胜者&#34 ;?我不知道从哪里开始实现一个展开树。
如果您能提供任何见解,我将非常感激。
public E theWinner(E[] C) {
int i = 0;
while (i < C.length) {
findCandidate(C[i], this.root);
}
// This is where I'm stuck, returning the winner in < O(n) time.
}
public void findNumber(E number, Node<E> root) {
if (root.left == null && root.right == null) {
this.add(number);
//splay tree?
} else if (root.data.compareTo(number) == 0) {
root.freqCount = root.freqCount + 1;
//splay tree?
} else {
if ( root.data.compareTo(number) < 0) {
findNumber(number, root.right);
} else {
findNumber(number, root.left);
}
}
}
答案 0 :(得分:2)
你不需要一棵展开树。 Getfiles()
为O(n log m + m)
,因为不同元素O(n log m)
的数量不大于元素m
的总数。因此,您可以在处理输入序列后迭代树中的所有元素以找到最大值。