for (int i = 1; i <= n; ++i)
for (int j = 1; j <= n; j += pow(i, 2))
//some O(1) operation
What would be the time complexity for this snippet? For each i in the outer loop, I calculate the how many operations the inner loop will perform, and found:
But I don't know how to do the math... And what if I change the pow part to pow(i, 3) or higher power?
Any help is appreciated!
edit: sorry, but I figured I was trying to ask
for (int i = 1; i <= n; ++i)
for (int j = 1; j <= n; j *= i)
//some O(1) operation
And by higher power, I mean j *= (i * i) or j *= i * i * i... and so on.
Sorry again for the wrong question...
If I am understanding your code correctly, there shouldn't be logarithms involved. The total number of steps should be
n + n/2 + n/2^2 + n/3^2 + ...
This is a geometric series. It sums to 2n.
EDIT: As pointed out in the comments, it is not geometric. The correct sum is pi^2/6*n, see https://en.wikipedia.org/wiki/Basel_problem . But still is is O(n).
The complexity is O(n)
as @paragon showed. Also, sometimes simply counting how many iterations occour will often reveal the complexity:
#include <iostream>
unsigned f(unsigned n) {
unsigned ctr = 0u;
for (int i = 1; i <= n; ++i) {
for (int j = 1; j <= n; j += pow(i, 2)) {
++ctr;
}
}
return ctr;
}
int main() {
for (unsigned n = 1u; n < 9u; ++n) {
unsigned a = std::pow(10, n) * 2;
unsigned b = std::pow(10, n);
std::cout << "f(" << a << ") / f(" << b << ") = " << f(a) / static_cast<double>(f(b)) << '\n';
}
}
showing that it clearly approaches a O(n)
complexity:
f(20) / f(10) = 2.09091
f(200) / f(100) = 2.04016
f(2000) / f(1000) = 2.01001
f(20000) / f(10000) = 2.0035
f(200000) / f(100000) = 2.00105
f(2000000) / f(1000000) = 2.00032
f(20000000) / f(10000000) = 2.0001
f(200000000) / f(100000000) = 2.00003
And what if I change the pow part to pow(i, 3) or higher power?
it will stay still be O(n)
. It makes sense, because the higher the exponent, the larger j
grows completing its loop even earlier reducing the complexity to the that of the i
loop ( i <= n
=> O(n)
):
[pow = 1] f(20000000) / f(10000000) = 2.08026
[pow = 2] f(20000000) / f(10000000) = 2.0001
[pow = 3] f(20000000) / f(10000000) = 2.00001
[pow = 4] f(20000000) / f(10000000) = 2
[pow = 5] f(20000000) / f(10000000) = 2
[pow = 6] f(20000000) / f(10000000) = 2
[pow = 7] f(20000000) / f(10000000) = 2
//...
adding to @paragon's answer, the series is
where p
is the exponent. As x
grows, the fraction shrinks making the sum approach a fixed value (except for small values of p
I think)
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.