@Jon is close but his analysis is a bit wrong, and the real complexity of your algorithm is O(n*sqrt(n))
.
This is based on the fact that for each number i
, the expected number of 'work' you should do in the inner loop is:
1/2 + 2/3 + 3/4 + ... + (sqrt(i)-1)/sqrt(i) =
= 1-1/2 + 1-1/3 + ... + 1-1/sqrt(i)
= sqrt(i) - (1/2 + 1/3 + ... + 1/sqrt(i)
= sqrt(i) - H_sqrt(i)
since H_sqrt(i)
(The harmonic number) is in O(log(sqrt(i)) = O(1/2*log(i)
, we can conclude that the complexity is O(sqrt(i)-log(i)) = O(sqrt(i))
, per prime number calculation.
Since this is done repeatedly per each i
, the total complexity of the problem is O(sqrt(2) + sqrt(3) + ... + sqrt(n))
. According to this forum thread, the sum of squared roots is in O(n*sqrt(n))
, which is "worse" than O(nlogn)
.
Things to notice:
- The first sum is up to sqrt(i) since this is the point where
j > (i / j)
. - The first sum is
(j-1)/j
for eachj
, because on average one out ofj
elements is getting into the break (1/3 of the elements are dividable by 3, 1/4 by 4,...) this leaves us(j-1)/j
that are not - and this is the expected work we have. - The equality
O(log(sqrt(n)) = O(1/2*log(n)
comes fromO(log(n^k))=O(k*log(n))=O(log(n))
for any constantk
. (in your case k=1/2)