设一个大小为n
的数组。我们需要编写一个算法来检查是否有一个至少出现n/loglogn
次的数字。
我已经明白在O(n*logloglogn)
中有一种方法可以做到这一点:
n/loglogn
,我们会返回true
。需要O(n)
。O(n)
n/2
数组)。n/loglogn
的子阵列,请停止并返回false。问题:
T(n) = 2T(n/2) + O(n)
,基本情况为T(n/loglogn) = O(1)
。现在,重复树中调用的最大数量是O(logloglogn)
,并且由于每个调用都是O(n)
,因此时间复杂度为O(n*logloglogn)
。那是对的吗? 答案 0 :(得分:1)
建议的解决方案有效,复杂性确实是O(n/logloglog(n))
。
假设“pass i”是深度i
的所有递归调用的运行。请注意,每次传递都需要O(n)
时间,因为虽然每次调用都远小于O(n)
,但有几次调用 - 总的来说,每个元素在每个“传递”中处理一次。
现在,我们需要找到传球次数。这是通过求解等式来完成的:
n/log(log(n)) = n / 2^x
<->
n/log(log(n)) * 2^x = n
这个想法是每次调用都将数组除以一半,直到达到预定义的n/log(log(n))
大小。
O(n/log(log(log(n)))
中的x确实解决了这个问题,因为you can see in wolfram alpha,因此复杂性确实是O(nlog(log(log(n))))
至于正确性 - 那是因为如果一个元素重复超过要求 - 它必须在一些子数组中,其大小大于/等于所需的大小,并且通过不断减小数组的大小,你将得到一个案例某些地方#repeats <= size(array) <= #repeats
- 在这一点上,你将找到这个元素作为中位数,并发现它确实是一个“常用项目”。
O(n/log(log(n))
时间内的其他一些方法 - Karp-Papadimitriou-Shanker提出了一些很好的常量,它基于在处理数组时用“候选者”填充表格。