Show that the time complexity of this double loop is O(n) - complexity-theory

How would you show that this entire sequence of loops is O(n)? Or is it O(n)? At first glance, just looking at the double loops one might think it's O(n^2) but I don't think it is...
int i = 0;
int arr[N];
int idx = 0;
for (i = 0; i < 2; i++)
{
for (j = 0; j < N/2; j++)
{
idx = (i * N/2) + j;
foo(arr[idx]);
}
}

The outer loop is constant, so the loop is the same as doing:
for (j = 0; j < N/2; j++)
{
idx = (0 * N/2) + j;
foo(arr[idx]);
idx = (1 * N/2) + j;
foo(arr[idx]);
}
Which actually makes the intent of the code a lot clearer also, but as you can see, the amount of operations scales linearly with N, so it's O(N) complexity rather than exponential growth. I can't explain it any better as it's 8.30am and I haven't slept, but I imagine you get my gist.

Related

What’s the time complexity of the this function with a nested 'for' loop?

Consider:
bar (a) {
for (int i = 0; i < n; ++i)
for (int j = 0; j < i; ++j)
a = a * (i + j);
return a;
}
Find the time complexity for the above function.
The time complexity is O(n^2).
Since the inner for loop runs from 0 to i and outer for loop runs from 0 to n it follows the pattern 1 + 2 + ... + n and this sums up to n*(n-1)/2, which in turn is O(n^2)

Time Complexity for for loop with if-else block

I want to find the time complexity for this below code. Here's my understanding-
The outer for loop will loop 2n times and in the worst case when i==n, we will enter the if block where the nested for loops have complexity of O(n^2), counting the outer for loop, the time complexity for the code block will be O(n^3).
In best case when i!=n, else has complexity of O(n) and the outer for loop is O(n) which makes the complexity, in best case as O(n^2).
Am I correct or am I missing something here?
for (int i = 0; i < 2*n; i++)
{
if (i == n)
{
for (int j = 0; j < i; j++)
for (int k = 0; k < i; k++)
O(1)
}
else
{
for (int j = 0; j < i; j++)
O(1)
}
}
No.
The question "what is T(n)?".
What you are saying is "if i=n, then O(n^3), else O(n^2)".
But there is no i in the question, only n.
Think of a similar question:
"During a week, Pete works 10 hours on Wednesday, and 1 hour on every other day, what is the total time Pete works in a week?".
You don't really answer "if the week is Wednesday, then X, otherwise Y".
Your answer has to include the work time on Wednesday and on every other day as well.
Back in your original question, Wednesday is the case when i=n, and all other days are the case when i!=n.
We have to sum them all up to find the answer.
This is a question of how many times O(1) is executed per loop. The time complexity is a function of n, not i. That is, "How many times is O(1) executed at n?"
There is one run of a O(n^2) loop when i == n.
There are (2n - 2) instances of the O(n) loop in all other cases.
Therefore, the time complexity is O((2n - 2) * n + 1 * n^2) = O(3n^2 - 2*n) = O(n^2).
I've written a C program to spit out the first few values of n^2, the actual value, and n^3 to illustrate the difference:
#include <stdio.h>
int count(int n){
int ctr = 0;
for (int i = 0; i < 2*n; i++){
if (i == n)
for (int j = 0; j < i; j++)
for (int k = 0; k < i; k++)
ctr++;
else
for (int j = 0; j < i; j++)
ctr++;
}
return ctr;
}
int main(){
for (int i = 1; i <= 20; i++){
printf(
"%d\t%d\t%d\t%d\n",
i*i, count(i), 3*i*i - 2*i, i*i*i
);
}
}
Try it online!
(You can paste it into Excel to plot the values.)
The First loop is repeated 2*n times:
for (int i = 0; i < 2*n; i++)
{
// some code
}
This part Just occur once, when i == n and time complexity is : O(n^2):
if (i == n)
{
for (int j = 0; j < i; j++)
for (int k = 0; k < i; k++)
O(1)
}
And this part is depends on i.
else
{
for (int j = 0; j < i; j++)
O(1)
}
Consider i when:
i = 0 the loop is repeated 0 times
i = 1 the loop is repeated 1 times
i = 2 the loop is repeated 2 times
.
.
i = n the loop is repeated n times. (n here is 2*n)
So the loop repeated (n*(n+1)) / 2 times But when i == n else part is not working so (n*(n+1)) / 2 - n and time complexity is O(n^2).
Now we sum all of these parts: O(n^2) (first part) + O(n^2) (second part) because the first part occurs once so it's not O(n^3). Time complaxity is: O(n^2).
Based on #Gassa answer lets sum up all:
O(n^3) + O((2n)^2) = O(n^3) + O(4n^2) = O(n^3) + 4*O(n^2) = O(n^3)
Big O notation allows us throw out 4*O(n^2) because O(n^3) "eats" it

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

Big O notation of nested sequential loops

I have been searching through the forums on big O notation and learned quite a bit. My problem is pretty specific and I think a unique case will better help me understand big O, I am ignoring constants.
To my understanding if a loop goes through all elements than it's O(n).
for(int i = 0; i < n; i++)
{
}
If a loop goes through all of n, inside another loop that goes through all of n, it's multiplied n * n = n^2
for(int i = 0; i < n; i++)
{
for(int j = 0; j < n; j++)
{
}
}
Lastly if a loop is followed by another loop that goes through all elements it is n + n = 2n
for(int j = 0; j < n; j++)
{
}
for(int k = 0; k < n; k++)
{
}
My question directly proceeds these lines of code
for(int i = 0; i < n; i++)
{
for(int j = 0; j < n; j++)
{
}
for(int k = 0; k < n; k++)
{
}
for(int l = 0; l < n; l++)
{
for(int m = 0; m < n; m++)
{
}
}
}
So based on the rules above I am calculating big O to be n * (n + n + n * n), which is n^3 + 2n^2. So would that make my big O(n^3) or would my big O be O(n^3 +2n^2). Am I going about this all wrong? Or am I somewhere close in the ballpark? Mainly I'm trying to figure out if these loops would be less than O(n^4). Thanks in advance.
The big-O notation is used to characterize the asymptotic behavior of an algorithm depending on some value n that indicates the data volume, but independent of any constant, e.g. processor speed.
In your example, n^3 grown faster than 2n^2, i.e., for large n, 2n^2 can be neglected compared to n^3. The asymptotic behavior of your nested loops thus have order O(n^3).

Big Oh Logarithmic(ish) complexity calculation

So I've been trying to get a handle on Big Oh calculations. I feel I have the basics down but am stumped on what seems a really easy calculation. So if the calculation below has a big oh of O(n log n) (I really hope I've at least got that right) what does changing the order of the loops do to the complexity? Thanks so much in advance for your time.
int ONLogN(int N) //O(n log n)
{
int iIterations = 0;
for (int i = 0; i < N; ++i)
{
++iIterations;
for (int j = 1; j < N + 1; j *= 2)
++iIterations;
}
return iIterations;
}
int WhatBigOhIsThis(int N) //???
{
int iIterations = 0;
for (int j = 1; j < N + 1; j *= 2)
{
++iIterations;
for (int i = 0; i < N; ++i)
++iIterations;
}
return iIterations;
}
The index variables on the two loops are independent, hence the resulting complexity is necessarily the same.
You're still looping for the same number of iterations. Changing the order of the loops would have no effect on complexity

Resources