我需要找到以下片段的大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)。
答案 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)。