我正在网上参加一门课程并坚持以下问题。以下代码片段的最坏情况运行时间的增长顺序是N?
的函数int sum = 0;
for (int i = 1; i <= N*N; i++)
for (int j = 1; j <= i; j++)
for (int k = 1; k <= j; k++)
sum++;
我认为它是N^4
的顺序,但似乎这个答案是错误的。你能解释一下吗?
答案 0 :(得分:6)
它是O(N^6)
的顺序。您应该注意,每个循环都只是为复杂性添加了一个订单N
。考虑以下示例:
int sum = 0;
for (int i = 1; i <= M; i++)
for (int j = 1; j <= i; j++)
for (int k = 1; k <= j; k++)
sum++;
你应该能够很容易地发现它是O(M^3)
的顺序,所以如果你替换M=N^2
,那么你就会得到答案。关键点在于,在这种情况下,每个内部循环的顺序为O(N^2)
,但不是O(N)
。
答案 1 :(得分:3)
我们用n = N^2
表示。然后,每次k <= i <= j
时都会执行循环。这将大约n^3/6
次。因此,运行时为O(n^3)= O(N^6)
解释:暂时忽略k==i
或j==i
或j==k
的情况,
我们从6个不同的三元组中选择1个:
(a1,a2,a3)
(a1,a3,a2)
(a2,a1,a3)
(a2,a3,a1)
(a3,a2,a1)
(a3,a1,a2)
总体而言,有n^3
三倍。 6个三元组中只有一个服从命令。
答案 2 :(得分:2)
内部循环的一次运行恰好sum
次增加j
次。
中间循环的一次运行恰好i
次调用内循环,j
和1
之间的值i
。因此,sum
恰好1+2+3+...i
次增加i.(i+1)/2
次,这是众所周知的“三角数”公式。{/ p>
外部循环恰好N^2
次调用中间循环(让我们将其表示为M
),i
和1
之间的值为M
(包括的)。因此,sum
恰好1+3+6+...M.(M+1)/2
次增加M.(M+1).(M+2)/6
次。同样,这是sum
,由不太知名的“四面体数”公式(http://en.wikipedia.org/wiki/Tetrahedral_number)。
总而言之,N^2.(N^2+1).(N^2+2)/6
的最终价值为O(j)
。
以渐近项思考,内循环为O(i^2)
,中间循环为O(M^3)
(通过求和),外循环为O(N^6)
(通过求和),即n^k
另请参阅Faulhaber的公式,其中显示O(N^(k+1))
的总和为{{1}}(http://en.wikipedia.org/wiki/Faulhaber%27s_formula)。
答案 3 :(得分:1)
最内层(k)循环的任何给定运行都具有与j成比例的时间,但是我们必须为j = 1到j = i中的每一个执行其中一个,并且总和1 + 2 + ... +我像i ^ 2一样成长。因此,对于任何给定的 i,我们有一个O(i ^ 2)运行时间,但当然我们必须处理i = 1到i = N ^ 2。 i ^ 2的总和为i = 1到N ^ 2 happens to grow like N^6。