代码片段的渐近分析

时间:2009-10-10 17:26:21

标签: big-o analysis

我需要找到以下片段的大O运行时间:

sum =0; 
for (int i=1; i<n; i++) {
  for (int j=1; j< n/i; j++) {
    sum = sum +j;
  }
}

我知道外循环是O(n)但是我在分析内循环时遇到了问题。我认为这是O(log n)。

3 个答案:

答案 0 :(得分:7)

让我们用这种伪数学风格来写这个。

sum i <- [1..n] (sum j <- [1..n/i] 1)

内循环(总和)需要

n / i

迭代,这使得整个术语

sum i <- [1..n] (n/i)

根据分配法简化总和:

n * (sum i <- [1..n] (1/i))

内部总和很大程度上类似于1/x上的积分,它是对数的。

所以O(n log n)是对的。

答案 1 :(得分:4)

最好的方法是考虑算法将采取多少步骤。

如果你有n个元素,你知道外部循环将至少运行n次。所以它必须至少是O(n)。

内圈必须为每个i运行多少次?它会随着我的增加而增加,保持不变或减少吗?

很明显,内循环中的步数随着i的增加而减少,更重要的是,它会非线性地减少。所以你知道它没有O(n ^ 2)那么糟糕。

所以它介于O(n)和O(n ^ 2)之间......稍微分析一下内循环中的步骤减少应该会让你到那里。编辑:......虽然看起来人们已经放弃了它:)

答案 2 :(得分:1)

正如Dave所说,它是O(n log n),因为内部循环是O(log n)。