What is complexity of following code? - c

Find the time complexity of following code.
Answer given is O(log(n)*n^1/2), but I am not getting it.
I want someone to explain this.
i=n;
while(i>0)
{
k=1;
for(j=1;j<=n;j+=k)
k++;
i=i/2;
}

Take this code segment:
k=1;
for(j=1;j<=n;j+=k)
k++;
The values of j over various iterations will be 1, 3, 6, 10, 15, 21, 28, ....
Note that these numbers have closed form (m+1)(m+2)/2, where m is the number of iterations that have gone by. If we want to know how many iterations this loop will run for, we need to solve (m+1)(m+2)/2 = n, which has solution m = (sqrt(8n + 1) - 3))/2 = O(sqrt(n)). So this loop will run O(sqrt(n)) times.
The outer loop will run O(log(n)) times (this is rather easy to see). So overall, we have O(log(n)sqrt(n)).
edit: Or perhaps easier than solving (m+1)(m+2)/2 = n directly would simply be to note that (m+1)(m+2)/2 = O(m^2), and so O(m^2) = n implies m = O(sqrt(n)).

The complexity would be :
(log n + 1)*(-1 + squareroot(1+4n))/2 = O(squareroot(n)*log n)
log n is in base 2.
Suppose n is 36.
The outer loop will iterate for log n + 1 times because the value is halved every time 36,18,9,4,2,1.
The inner loop has j values = 1,3,6,10,15,21,28,36.Every j value can be calculated as the sum of terms in AP 1+2+3+4+5....w = w(w+1)/2. So w(w+1)/2 = n.Solving this quadratic equation we get w=(-1+sqrt(1+4n))/2 i.e the number of iterations of inner loop.
For n=36, w=8.
Total complexity thus comes out to be : log n * sqrt(n).

Related

time complexity of nested loops - always just a multiplication of each of them seperated?

When looking at this code for example :
for (int i = 1; i < n; i*=2)
for (int j = 0; j < i; j +=2)
{
// some contstant time operations
}
Is it as simple as saying that because the outer loop is log and and inner loop is n , that combined the result is big(O) of nlogn ?
Here is the analysis of the example in the question. For simplicity I will neglect the increment of 2 in the inner loop and will consider it as 1, because in terms of complexity it does not matter - the inner loop is linear in i and the constant factor of 2 does not matter.
So we can notice, that the outer loop is producing is of values which are powers of 2 capped by n, that is:
1, 2, 4, 8, ... , 2^(log2 n)
these numbers are also the numbers that the "constant time operation" in the inner loop is running for each i.
So all we have to do is to sum up the above series. It is easy to see that these are geometric series:
2^0 + 2^1 + 2^2 + ... + 2^(log2 n)
and it has a well known solution:
(from Wiki )
We have a=1, r=2, and... well n_from_the_image =log n. We have a same name for different variables here, so it is a bit of a problem.
Now let's substitute and get that the sum equals
(1-2^((log2 n) + 1) / (1 - 2) = (1 - 2*n) / (1-2) = 2n-1
Which is a linear O(n) complexity.
Generally, we take the O time complexity to be the number of times the innermost loop is executed (and here we assume the innermost loop consists of statements of O(1) time complexity).
Consider your example. The first loop executes O(log N) times, and the second innermost loop executes O(N) times. If something O(N) is being executed O(log N) times, then yes, the final time complexity is just them multiplied: O(N log N).
Generally, this holds true with most nested loops: you can assume their big-O time complexity to be the time complexity of each loop, multiplied.
However, there are exceptions to this rule when you can consider the break statement. If the loop has the possibility of breaking out early, the time complexity will be different.
Take a look at this example I just came up with:
for(int i = 1; i <= n; ++i) {
int x = i;
while(true) {
x = x/2;
if(x == 0) break;
}
}
Well, the innermost loop is O(infinity), so can we say that the total time complexity is O(N) * O(infinity) = O(infinity)? No. In this case we know the innermost loop will always break in O(log N), giving a total O(N log N) time complexity.

What is the time complexity of the following dependent loops?

I have a question that needs answer before an exam I'm supposed to have this week.
i = 1;
while (i <= n)
{
for (j = 1; j < i; j++)
printf("*");
j *= 2;
i *= 3;
}
I have those dependent loops, I calculated the outer loop's big O to be O(logn).
The inner loop goes from 1 to i - 1 for every iteration of the outer loop,
the problem I'm having with this is that I do not know how calculate the inner loop's time complexity, and then the overall complexity (I'm used to just multiplying both complexities but I'm not sure about this one)
Thanks a lot!
P.S: I know that the j *= 2 doesn't affect the for loop.
As you recognized, computing the complexity of a loop nest where the bounds of an inner loop vary for different iterations of the outer loop is not as easy a simple multiplication of two iteration counts. You need to look more deeply to get the tightest possible bound.
The question can be taken to be asking about how many times the body of the inner loop is executed, as a function of n. On the first outer-loop iteration, i is 1, so j is never less than i, so there are no inner-loop iterations. Next, i is 3, so there are two inner-loop iterations, then eight the next time, then 26 ... in short, 3i-1 - 1 inner-loop iterations. You need to add those all up to compute the overall complexity.
Well, that sum is Σi = 1, floor(log n) (3i-1 - 1), so you could say that the complexity of the loop nest is
O(Σi = 1, floor(log n) (3i-1 - 1))
, but such an answer is unlikely to get you full marks.
We can simplify that by observing that our sum is bounded by a related one:
= O(Σi = 1, floor(log n) (3i-1))
. At this point (if not sooner) it would be useful to recognize the sum of powers pattern therein. It is often useful to know that 20 + 21 + ... 2k - 1 = 2k - 1. This is closely related to base-2 numeric representations, and a similar formula can be written for any other natural number base. For example, for base 3, it is 2 * 30 + 2 * 31 + ... 2 * 3k - 1 = 3k - 1. This might be enough for you to intuit the answer: that the total number of inner-loop iterations is bounded by a constant multiple of the number of inner-loop iterations on the last iteration of the outer loop, which in turn is bounded by n.
But if you want to prove it, then you can observe that the sum in the previous bound expression is itself bounded by a related definite integral:
= O(∫0log n 3i di)
... and that has a closed-form solution:
= O((3log n - 30) / log 3)
, which clearly has a simpler bound itself
= O(3log n)
. Exponentials of logarithms reduce to linear functions of the logarithm argument. Since we need only an asymptotic bound, we don't care about the details, and thus we can go straight to
= O(n)

What is time complexity of fun()?

what is run time in function exe:log(n)
int fun(int n) {
int count = 0;
for (int i = n; i > 0; i /= 2)
for (int j = 0; j < i; j++)
count += 1;
return count;
}
It's not O(log n), but it is O(n). You can think about it like this: Each run of the outer loop sends the remaining data (originally n) into the inner loop for processing, and then removes one half of it. The inner loop is clearly linear in the data it processes.
At first iteration, the outer loop sends the whole n into the inner loop, which "pays" n steps for processing it.
At the second iteration, there is n / 2 data left, so the innter loop pays n / 2 for it; it has payed 1.5n in total.
At the next iteration, there is n / 2 / 2 == n/4 data left, for which the inner loop pays an extra n/4, so 1.75n in total.
And so on, until the entire n has been paid for twice, so the cost is 2n, which is O(n), actually even ϴ(n).
The complexity would be
O(n)
For example suppose we take n=32
so for various iterations the number of times loop will run is
32,16,8,4,2,1
So on adding it will be 63 which is the total number of times loop ran
and that is 2*n-1
Mathematically ,for any value which it is a G.P Sum where the series is like n,n/2,n/4,n/8......1
suppose we take n=32 again
then
sum = a * (1-r^nof)/(1-r) = 32 * (1-(1/2)^5)/(1-(1/2)) = 63
where nof(number of times outer loop ran)=5 is log2n, a=32, r=(1/2)
for any number it will be less than 2*n
The Time Complexity of your code is O(n) only.

Calculating Time Complexity for nested loops

Got this question on a test that I've been stuck on for a few days regarding Big O time complexity analysis:
Below is the C code:
if ( A > B ) {
for ( i=0; i<n^2/100; i++ ){ //1
for ( j=n^2; j>i; j-- ){ //2
A += B;}}
}
else {
for ( i=0; i<2n; i++ ){ //3
for ( j=3n; j>i; j-- ){ //4
A += B;}}
}
My first instinct was that this algorithm would have a big O of O(n2) with the nested for loops and such but it wasn't a multiple choice answer. Tried to count each loop iteration manually but having trouble accounting for the changing i in each inside loop (2 and 4). Also having trouble trying to write it as a summation.
Consider the first case where A > B. The inner loop executes a number of iterations equal to n^2 - i for each value of i iterated over by the outer loop. Consider n = 2 and i = 1. n^2 = 4 and the inner loop iterates over j = 4, j = 3, j = 2, three iterations, consistent with our finding.
The total number of iterations of the inner loop is therefore the sum of all n^2 - i where i varies from 0 to floor(n^2/100) - 1. Let us define k := floor(n^2/100) - 1. Then this sum is equal to kn^2 - k(k+1)/2. Substituting the expression for which k stands we recover [floor(n^2/100) - 1]n^2 - [floor(n^2/100) - 1][floor(n^2/100)]/2. This is no greater than (n^2/100 - 1)n^2 - (n^2/100 - 1)(n^2/100)/2. We may multiply through to get n^4/100 - n^2 - n^4/20000 + n^2/200 = n^4(1/100 - 1/20000) - n^2(1 - 1/200). From this we can see that the time complexity of the first case is O(n^4). Indeed, it is also Omega(n^4) and Theta(n^4).
In the case where A <= B, the analysis is similar. It is easy to show that the time complexity of the second case is O(n^2), Omega(n^2) and thus Theta(n^2).
Therefore, we may confidently say that:
The worst-case time complexity is O(n^4);
The best-case time complexity is Omega(n^2);
Each of these bounds may actually be given as Theta bounds instead.

Runtime of an easy while loop

I have a short question about the runtime of a while loop.
I have the given code:
Calculate(int n)
i = n
while(i > 0)
i = i/2
If n is a power of two, how often will the while loop be executed. I am doing revision on something we did at the beginning of the semester and I know it's not hard but I just don't know how the answer. For example if n = 1, the loop would be executed one time, if n = 2, the then loop would be executed 2 times, if n = 4, the loop would be executed 3 times and so on but I am not sure how to formulate that mathematically.
A mathematical formula for this will use the binary logarithm:
log2(n) + 1

Resources