Time complexity for two nested for loops - time

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.

Related

What is the time complexity for this loop

How can we find the time complexity for this loop
int c = 0;
int j = 1;
while (j< n^3) {
c+=1;
System.out.println(c);
j=j*4;
}
Since every time j is multiplied by 4 we can say after every iteration it can be written as :
1, 4, (4^2), ..., (4^k)
Now for loop to be false, (4^k) >= n^3
4^k >= n^3
k = log(n^3) to the base 4
You can further simplify it to:
3log(n) to base 4 and remove 3 as we do for constants.
k = log(n)
This should be the complexity of your loop.

What is the big-O of this program where nested loops depend on each other?

Can't figure out what the big O for this block of code is. Outer loop is log(n), but how bout inner loop that depends on outer loop?
for (int i = 1; i < A.length; i = i * 3) {
for (int j = i; j < A.length; j++) {
// Simple computation
}
}
Any help greatly appreciated :)
If A.Length == n, the inner loop runs in n-i each time. Hence, the total complextiy of the program is sum(n - i) for i = 1, 3, 9, ..., n = 3^log_3(n). As the number of i is log_3(n), the complexity is T(n) = n * log_3(n) - (3^(log_3(n)+1)-1) = n * log_3(n) - 3(n-1) = O(nlog(n))
As is your code will not complete because i = i * 3 means that i will always be 0.
From your comment it is supposed to be i = 1. So, on each iteration of the outer loop, the problem size is reduced by a constant factor of 3. This means that the outer loop takes O(log n) steps.
The inner loop takes O(n) in the worst case and is run O(log n) times. Therefore, the entire running time is O(n log n).
Be sure to check your post for typos and do some research in the future :).

Finding the complexity of Loops

I'm given this algorithm and I'm told to find the complexity of it big theta.
for (i = 1; i <= n; i++) {
j = n;
while( j >= 1) {
j = j/3;
}
}
I know outer for loop runs n times. The while loop is more tricky though, Is it possibly log n (of base 3). In total making it n*log3n
Is this correct?
There is an outer for loop of size n. It contributes a complexity of a factor of n to the over all complexity.
Let's say inner while loop runs for m times. After i'th iteration, the value of j will be n/(3^i). We will run this till n/(3^i) > 1. Therefore,
=> n/(3^i) = m
=> n = 3^m
=> log(n) = log2(3) * m
=> m = O(log(n))
So, for loop contributes to O(n) and while loop contributes to O(log(n)). Complexity of nested loop becomes O(n log(n)).

What is the Big-O of a nested loop, where the outer loop is n^2

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)

Explain the answer of this Big O complexity code

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))

Resources