【发布时间】:2020-01-23 18:20:53
【问题描述】:
我们什么时候将外循环的大 O 乘以内循环的平均大 O?
for (int i = n; i > 0; i /= 2) {
for (int j = 0; j < i; j++) {
//statement
}
}
Answer: O(n)
在这个问题中,外循环是 O(log n)。由于内部循环根据“i”执行了一定次数,因此采用平均大 O。这导致 n + n/2 + n/4 + ... = 2n 的总和,然后除以得到平均值:O(2n / log n)。
因此 O(log n) * O(2n / log n) = O(n)。
但是为什么我们不需要为这个问题取平均值呢?
for (i = 0; i < n; i++) {
for (j = 0; j < i * i ; j++){
}
}
Answer: O(n^3)
外循环是O(n)。内循环是 O(n^2)。但为什么呢?
内循环不是根据外循环中的“i”值执行的吗?那么为什么不像上面的问题那样取平均值呢? - 导致内部循环类似于 O(n^2 / n)。
【问题讨论】:
-
“我们什么时候将外循环的大 O 乘以内循环的平均大 O?” 从不。 “这导致 n + n/2 + n/4 + ... = 2n 的总和” 是的,这是正确的分析。 O(2n) 是 O(n)。
-
@user3386109 “从不”是什么意思?根据定义,平均值是总数除以迭代次数,因此这样做总是正确(但总是不方便)。
-
@kaya3 你回答了你自己的问题。要计算平均值,您首先需要计算总数。总数就是答案。
-
@user3386109 这是假设在不先计算总数的情况下,永远无法计算平均值(或者至少,它的大 O 表示法的顺序)。通常,有;一个明显的例子是
for i from 1 to n: for j from 1 to m: ...,其中n和m是独立的常量。另一种常见情况是for i from 1 to n: for j from 1 to i: ...,其中i的平均值为n/2,因此内部循环平均执行O(n)次。 -
不,当平均值计算起来很简单时,总和计算起来同样简单。关键是平均值没有告诉你总数没有告诉你的任何东西。计算平均值永远比计算总数更容易。因此,学生永远不应该计算(或猜测)平均值。
标签: algorithm time-complexity big-o