我总是无法分析随机算法的运行时间。如果有人能向我解释,我将不胜感激。
以我编写的以下代码为例;
它检查数组中至少发生n / 4次的元素。 (n是数组的大小)。它从数组中选取一个随机数,检查它是否发生了n / 4次。如果是,则返回它。否则,它会删除所有出现的元素并继续。
假设数组中至少有一个这样的元素至少发生n / 4次。
elements_left = n ;
frequency ( A[] )
{
k -> pick a random element from A[] ;
int count = 0;
int delete_count = 0;
for (i=0 ; i < elements_left ; i++)
{
if (a[i] = k)
count++ ;
}
if (count >= n/4)
return A[i] ;
exit ;
else
{
for (i=0 ; i < elements_left ; i++)
{
if (A[i] = k)
delete (A[i]) ;
delete_count ++ ;
}
elements_left = n - delete_count ;
}
frequency (A[])
}
这个算法的最坏情况运行时间和预期运行时间是什么?你将如何得出它?
感谢。
答案 0 :(得分:3)
考虑这一点的一种方法如下:在算法的每次迭代中,您将进行O(n)工作以检查您随机选择的元素是否是您想要的元素。如果是这样,你就完成了。如果没有,您需要做一些工作来从阵列中删除该元素的所有其他副本。上面的伪代码并没有真正指定你是如何删除它们的(我不知道这意味着删除单个数组元素),但我会假设运行时是O(n),因为它可以删除那个时候元素的所有副本。
现在的问题是,在期望中需要多少回合才能找到元素?由于该元素具有被选择的概率的1/4,因此在期望时将需要4次尝试才能找到它。每次尝试都做Θ(n)工作 - 总是在n / 4和n个总元素之间 - 因此运行时期望值为Θ(n)(Θ(n)工作的四次迭代。)
希望这有帮助!
答案 1 :(得分:2)
templatetypedef's answer描述了当元素出现n / 4次时的情况。
最坏情况下的运行时间为O(n ^ 2),如果所有项目都是唯一的,则会发生这种情况。
平均情况很难确定。假设数组包含100个项目。除了一个,它们都是独一无二的,它发生了15次。因此,您必须至少进行40次递归调用,以便为该单个项目删除足够的项目作为结果。但是在第一次迭代中,有15/100的机会你将删除最频繁的项目。下一次有15/99的机会等等。很有可能(几乎可以肯定)当你做出40次选择时,你会选择最频繁的项目并将其从数组中删除。
因此,如果您知道有一个元素出现n / 4次,则预期的运行时间为O(n)。否则,运行时高度依赖于项的分布,最坏的情况是运行时间为O(n ^ 2)。