Is the time complexity of this loop O(n*log(n))? - algorithm

I'd be very grateful if someone explained to me how to analyse the time complexity of this loop:
int t;
for (i = 1; i <= n; i++){
t = i;
while(t > 0){
t = t/2
}
}
I'm inclined to think that is O(n*log(n)) since it's very similar to:
int t;
for (i = 1; i <= n; i++){
t = n;
while(t > 0){
t = t/2
}
}
but it does less assignments to the variable t. Is this the case?
If it's the case, How could I arrive to this conclusion more rigorously?

For the first snippet, the inner loop runs log(1) + log(2) + ... + log(n) times, which is the same as log(1 * 2 * ... * n) = log(n!) which through Sterling's Approximation is n log(n). Your second snippet has the same complexity. Even if it happens to do less assignments we only care about the overall behavior. In this case both are linearithmic.

Related

some examples of algorithm complexity of nested loops?

I have seen that in some cases the complexity of nested loops is O(n^2), but I was wondering in which cases we can have the following complexities of nested loops:
O(n)
O(log n) I have seen somewhere a case like this, but I do not recall the exact example.
I mean is there any kind of formulae or trick to calculate the complexity of nested loops? Sometimes when I apply summation formulas I do not get the right answer.
Some examples would be great, thanks.
Here is an example for you where the time complexity is O(n), but you have a double loop:
int cnt = 0;
for (int i = N; i > 0; i /= 2) {
for (int j = 0; j < i; j++) {
cnt += 1;
}
}
You can prove the complexity in the following way:
The first iteration, the j loop runs N times. The second iteration, the j loop runs N / 2 times. i-th iteration, the j loop runs N / 2^i times.
So in total: N * ( 1 + 1/2 + 1/4 + 1/8 + … ) < 2 * N = O(N)
It would be tempting to say that something like this runs in O(log(n)):
int cnt = 0;
for (int i = 1; i < N; i *= 2) {
for (int j = 1; j < i; j*= 2) {
cnt += 1;
}
}
But I believe that this runs in O(log^2(N)) which is polylogarithmic

What is the Big-O of this section of code?

x = 0;
for (i = 1; i <= n; i = i * 3) // Is big(O) of this statement O(log base 3 n)?
{
if (i % 2 != 0)
for (j = 0; j < i; j++) // What will be big(O) of this loop and how?
x++;
}
I read an answer that overall big-O will be O(n). How will be big(O) of this code O(n) if this is true?
The inner loop will execute i operations for each i from 0 to log_3(n). So the number of operations performed is given by this common sum. It has a closed form of (log_3(n) + 1)(log_3(n))/2 which is O([log n]^2)

Complexity of double-nested loop

What is the order of growth of the worst case running time of the following code fragment as a function of N?
int cnt = 0;
for (int i = 1; i <= N; i = i*4)
for (int j = 0; j < i; j++)
{ cnt++; }
I now for example that first loop execute ~log(4, N) times and the second loop execute ~N times. But how to combine this knowlege to find the answer?
What is the general way to find that kind of complexity?
Maybe, we need to know how much time the body of the inner loop is executed?
For example 1 + 4 + 16 + 64 + ... + N
Geometric progression = (x^n - 1)/(x-1) where n=Log(4,N), so the result is
(x^log(x, N) - 1)/ (x-1) = (4N - 1)/3
Let's N belong to the interval [4^k; 4^(k+1)), then we have got sum:
sum 4^i, i=0..k = (4^(k+1)-1)/3 = O(n)
I was late some minutes and minus...

running time of algorithm does not match the reality

I have the following algorithm:
I analyzed this algoritm as follow:
Since the outer for loop goes from i to n it iterates at most n times,
and the loop on j iterates again from i to n which we can say at most n times,
if we do the same with the whole algorithm we have 4 nested for loop so the running time would be O(n^4).
But when I run this code for different input size I get the following result:
As you can see the result is much closer to n^3? can anyone explain why does this happen or what is wrong with my analysis that I get a loose bound?
Formally, you may proceed like the following, using Sigma Notation, to obtain the order of growth complexity of your algorithm:
Moreover, the equation obtained tells the exact number of iterations executed inside the innermost loop:
int sum = 0;
for( i=0 ; i<n ; i++ )
for( j=i ; j<n ; j++ )
for( k=0 ; k<j ; k++ )
for( h=0 ; h<i ; h++ )
sum ++;
printf("\nsum = %d", sum);
When T(10) = 1155, sum = 1155 also.
I'm sure there's a conceptual way to see why, but you can prove by induction the above has (n + 2) * (n + 1) * n * (n - 1) / 24 loops. Proof left to the reader.
In other words, it is indeed O(n^4).
Edit: You're count increases too frequently. Simply try this code to count number of loops:
for (int n = 0; n < 30; n++) {
int sum = 0;
for (int i = 0; i < n; i++) {
for (int j = i; j < n; j++) {
for(int k = 0; k < j; k++) {
for (int h = k; h < i; h++) {
sum++;
}
}
}
}
System.out.println(n + ": " + sum + " = " + (n + 2) * (n + 1) * n * (n - 1) / 24);
}
You are having a rather complex algorithm. The number of operations is clearly less than n^4, but it isn't at all obvious how much less than n^4, and whether it is O (n^3) or not.
Checking the values n = 1 to 9 and making a guess based on the results is rather pointless.
To get a slightly better idea, assume that the number of steps is either c * n^3 or d * n^4, and make a table of the values c and d for 1 <= n <= 1,000. That might give you a better idea. It's not a foolproof method; there are algorithms changing their behaviour dramatically much later than at n = 1,000.
Best method is of course a proof. Just remember that O (n^4) doesn't mean "approximately n^4 operations", it means "at most c * n^4 operations, for some c". Sometimes c is small.

Time complexity (in big-O notation) of the following code?

I was just wondering what is the time complexity of the following code.
The time complexity (Big O) of the code below in my opinion would be O(n^4)
What do you guys think?
int result = 0;
for(int i =1; i<n*n; i++){
for (int j=i; j*j <n; j++){
for(int k =j; k*k <n; k++){
result++;
}
}
}
Looks like n^(2.75) to me:
- outer loop: n^2
- first inner loop is sqrt(n)
- second inner loop is sqrt(sqrt(n))
Total of:
n^2 * sqrt(n) * sqrt(sqrt(n)) = n^(2+ 0.5 + 0.25) = n^(2.75)
Formal steps (need to be verified) using Sigma Notation would yield the following:

Resources