Reputation: 612
I am doing the exercise of Skiena's book on algorithms and I am stuck in this question:
I need to calculate the big O of the following algorithm:
function mystery()
r=0
for i=1 to n-1 do
for j=i+1 to n do
for k=1 to j do
r=r+1
Here, the big O of the outermost loop will be O(n-1) and the middle loop will be O(n!). Please tell me if I am wrong here.
I am not able to calculate the big O of the innermost loop.
Can anyone please help me with this?
Upvotes: 2
Views: 296
Reputation: 1148
Here's a more rigorous way to approach solving this problem:
Define the run-time of the algorithm to be f(n)
since n
is our only input. The outer loop tells us this
f(n) = Sum(g(i,n), 1, n-1)
where Sum(expression, min, max)
is the sum of expression
from i = min
to i = max
. Notice that, the expression in this case is an evaluation of g(i, n)
with a fixed i
(the summation index) and n
(the input to f(n)
). And we can peel another layer and defineg(i, n)
:
g(i, n) = Sum(h(j), i+1, n), where i < n
which is the sum of h(j)
where j
ranges of i+1
to n
. Finally we can just define
h(j) = Sum(O(1), 1, j)
since we've assumed that r = r+1
takes time O(1)
.
Notice at this point that we haven't done any hand-waving, saying stuff like "oh you can just multiply the loops together. The 'innermost operation' is the only one that counts." That statement isn't even true for all algorithms. Here's an example:
for (i = 0; i < n; i++)
{
for (j = 0; j < n; j++)
{
Solve_An_NP_Complete_Problem(n);
for (k = 0; k < n; k++)
{
count++;
}
}
}
The above algorithm isn't O(n^3)
... it's not even polynomial.
Anyways, now that I've established the superiority of a rigorous evaluation (:D) we need to work our way upwards so we can figure out what the upper bound is for f(n)
. First, it's easy to see that h(j)
is O(j)
(just use the definition of Big-Oh). From that we can now rewrite g(i, n)
as:
g(i, n) = Sum(O(j), i+1, n)
=> g(i, n) = O(i+1) + O(i+2) + ... O(n-1) + O(n)
=> g(i, n) = O(n^2 - i^2 - 2i - 1) (because we can sum Big-Oh functions
in this way using lemmas based on
the definition of Big-Oh)
=> g(i, n) = O(n^2) (because g(i, n) is only defined for i < n. Also, note
that before this step we had a Theta bound, which is
stronger!)
And so we can rewrite f(n)
as:
f(n) = Sum(O(n^2), 1, n-1)
=> f(n) = (n-1)*O(n^2)
=> f(n) = O(n^3)
You might consider proving the lower bound to show that f(n) = Theta(n^3)
. The trick there is note simplifying g(i, n) = O(n^2)
but keeping the tight bound when computing f(n)
. It requires some ugly algebra, but I'm pretty sure (i.e. I haven't actually done it) that you will be able to prove f(n) = Omega(n^3)
as well (or just Theta(n^3)
directly if you're really meticulous).
Upvotes: 2
Reputation: 14778
The analysis takes place as follows:
i = [1, n - 1]
, so the program would have linear complexity O(i) = O(n)
if, inside this loop, only constant operations were performed;i
, some operation is executed n
times -- starting from j = [i + 1, n - 1]
. This gives a total complexity of O(i * j) = O(n * n) = O(n^2)
;i
, and for each j
, k
times, with k
ranging from k = [j, n - 1]
. As j
begins with i + 1 = 1 + 1
, k
is assymptotically equal to n
, which gives you O(i * j * k) = O(n * n * n) = O(n^3)
.The complexity of the program itself corresponds to the number of iterations of your innermost operations -- or the sums of complexities of innermost operations. If you had:
for i = 1:n
for j = 1:n
--> innermost operation (executed n^2 times)
for k = 1:n
--> innermost operation (executed n^3 times)
endfor
for l = 1:n
--> innermost operation (executed n^3 times)
endfor
endfor
endfor
The total complexity would be given as O(n^2) + O(n^3) + O(n^3)
, which is equal to max(O(n^2), O(n^3), O(n^3))
, or O(n^3)
.
Upvotes: 2
Reputation: 36
It cannot be factorial. For example if u have two nested cycles the big O will be n^2, not n^n. So three cycles cannot give more than n^3. Keep digging ;)
Upvotes: 1