Assuming we have the following loop:
O(N) Loop
for (int i = 1; i <=n; i *= c) {
// some O(1) expressions
}
O(LogLogN) Loop
for (int i = 2; i <=n; i = pow(i, c)) {
// some O(1) expressions
}
For the O(LogLogN) Loop, we have:
Iteration [1] -> 2^(2^0)
Iteration [2] -> 2^(2^1)
Iteration [3] -> 2^(2^2)
Iteration [4] -> 2^(2^3)
Since 2^n is O(LogN), we can replace the above as 2^(2^k), or 2^c. As c is O(LogN), we can deduce that 2^c is O(LogLogN).
Am I on the right track?
Related
This is the loop structure :
for (int i = 1 ; i < n ; i++) {
for (int j = 0 ; j < n ; j += i) {
// do stuff
}
}
My guess was O(nlogn) as it clearly cannot be O(n^2) since the increment in j is increasing and it clearly cannot be O(n sqrt(n)) since the increment is not that high. But I have no idea how to prove it formally.
Each time complexity of the inner loop is based on the value of i is n/i. Hence, total time would be n + n/2 + n/3 + ... + n/n = n(1+1/2+1/3+...+1/n).
As we know 1+1/2+1/3+...+1/n is a harmonic sereis and asymptotically is log(n). Hence, the algorithm is run in O(nlog(n)).
This question is for revision from a past test paper just needed advice if I on the right track.
Work out the time complexity T(n) of the following piece of code in terms of number of operations for a given integer n:
for ( int k = n; k >0; k /= 3 ) {
for ( int i = 0; i < n; i += 2 ) {
// constant number C of elementary operations
}
for ( int j = 2; j < n; j = (j*j)) {
// constant number C of elementary operations
}
}
So I thought the outer loop would be O(logn), the first inner loop would be O(n) and the second inner loop would be O(logn). Just wanted to know if I had a rough idea and how to move forward from here.
There was recently a question somewhat similar few days ago for which I provided a step-by-step description of complexity analysis: https://stackoverflow.com/a/49093954/926701
The outer loop is indeed O(log3(n))
The first inner loop is indeed O(n)
The second inner loop is O(log2(log2(n)))
Informally, for the second loop, with j(k) the sequence of values taken by the index j of the for loop, we can write:
j(1) = 2, j(2) = j(1)^2 = 4, j(3) = j(2)^2 = 16, ..., j(k) = j(k-1)^2 >= n
=> j(k) = j(k-1)^2 = j(k-2)^4 = ... = j(1)^(2^k) = 2^(2^k)
=> k = log2(log2(n))
Since the number of operations in the inner loops is independent from that of the outer loop, we can multiply the complexity:
T(n) = O(log3(n) * (n + log2(log2(n))))
= O(n.log3(n))
because log2(log2(n)) << n as n -> +Inf.
for(int i = 1; i < n **2; i++)
{
for(int j = 1; j < i; j++)
{
s = s;
}
}
Since the Big O of the outter loop is O(n^2) would it still be multiplied by the inner loop making the total Big O notation be n(n^2) -> O(n^3)?
In the outer loop, i can take values from 1 to n^2. Then for each of those values, the inner loop goes from 1 to i. The number of operations performed for i=1 is 1, i=2 is 2, ..., i = n^2 is n^2.
So the total number of operations is the sum for i from 1 to n^2 of i. This is a well known series which has the closed form of (n^2)(n^2 + 1)/2 and that is O(n^4)
I think it is log(logn) because the cycle repeats log(logn) times...
j=1;
i=2;
while (i <= n) do {
B[j] = A[i];
j = j + 1;
i = i * i;
}
You are right, it is O(lg(lg n)) where lg stands for base 2 logarithm.
The reason being that the sequence of values of i is subject to the rule i = prev(i) * prev(i), which turns out to be 2, 2^2, 2^4, 2^8, ... for steps 1, 2, 3, 4, .... In other words, the value of i after k iterations is 2^{2^k}.
Thus, the loop will stop as soon as 2^{2^k} > n or k > lg(lg(n)) (Just take lg twice to both sides of the inequality. The inequality remains valid because lg is an increasing function.)
for( int bound = 1; bound <= n; bound *= 2 ) {
for( int i = 0; i < bound; i++ ) {
for( int j = 0; j < n; j += 2 ) {
... // constant number of operations
}
for( int j = 1; j < n; j *= 2 ) {
... // constant number of operations
}
}
}
The correct answer is O(n2). As I understand, the Of the first two for loops, they are "nested". Since bound goes from 1 to n, and i goes to bound. The third and fourth loops are not nested.
The third for loop has complexity O(n+2) , The fourth for loop has complexity O(log n)
Someone told me since n2 > n+2 + log n, algorithm is O(n2). (I'm really confused about this step)
I thought you are suppose to multiply each loop, so shouldn't it be log n(outer loop) * n(2nd outer loop) * n(third) * log N(fourth). how do I know which loop I need to add or multiply, and which loop's value should I take(do I take N over log N for the first two loops because N is smaller to process?
The complexity should be O(n3).
First consider the inner-most loops:
for( int j = 0; j < n; j += 2 ) {
... // constant number of operations
}
Index j takes values 0, 2, 4, 6, 8, ... up to n, so j can take at most n / 2 + 1 possible values, hence the complexity of this loop is O(n).
And for another inner-most loop:
for( int j = 1; j < n; j *= 2 ) {
... // constant number of operations
}
Index j takes values 1, 2, 4, 8, 16, ... up to n, so j can take at most log(n) + 1 possible values, hence the complexity of this loop is O(log(n)).
Therefore for any fixed bound and i, the total work done by the two inner-most loops is O(n) + O(log(n)) = O(n).
Now consider the two outer-most loops. Note that if the variable bound for the outer-most loop is k, then the loop indexed by i will loop exactly k times.
for( int bound = 1; bound <= n; bound *= 2 ) {
for( int i = 0; i < bound; i++ ) {
// work done by the inner-most loops
}
}
Since bound takes values 1, 2, 4, 8, ..., these two nested loops will loop:
1^2 + 2^2 + 4^2 + 8^2 + ... + (2^⌊log(n)⌋)^2
Note that this is just a geometric series with common ratio 4, so the summation gives us:
( 4(^(⌊log(n)⌋+1) - 1 ) / 3
= O(2^(2log(n))
= O(2^log(n^2))
= O(n^2)
Since the work done of the inner-most loops is independent of these two loops, the total complexity is given by O(n2) * O(n) = O(n3).
The first and second successive innermost loops have O(n) and O(log n)
complexity, respectively. Thus, the overall complexity of the innermost
part is O(n). The outermost and middle loops have complexity O(log n)
and O(n), so a straightforward (and valid) solution is that the overall
complexity is O(n^2*log(n))