Order of growth of as function of N - algorithm

I'm practicing with algorithm complexities, I thought all the codes below were quadratic in terms of the order of growth but since I need the order of growth as a function of N, I think that changes things and I don't know exactly how to work it out.
int sum = 0;
for(int n = N; n > 0; n/=2)
for(int i = 0; i < n; i++)
sum++
int sum = 0;
for(int i = 1; i < N; i*=2)
for(int j = 0; j < i; j++)
sum++
int sum = 0;
for(int i = 1; i < N; i*=2)
for(int j = 0; j < N; j++)
sum++

int sum = 0;
for(int n = N; n > 0; n/=2)
for(int i = 0; i < n; i++)
sum++
This is O(N), the inner loop runs total of N + N/2 + N/4 + ... + 1 times, this sum converges to 2N when N->infinity, and thus it is O(N).
int sum = 0;
for(int i = 1; i < N; i*=2)
for(int j = 0; j < i; j++)
sum++
This is very similar to case1, and I am going to leave it to you as practice. Follow the same approach I did there, and you will get the answer.
int sum = 0;
for(int i = 1; i < N; i*=2)
for(int j = 0; j < N; j++)
sum++
Here, the main difference is the inner loop does not depend on the variable of the outer loop. This means, regardless of value of i, inner loop is going to repeat N times.
So, you need to realize how many times the outer loop will repeat, and multiply it with N.
I leave it as well for you as practice after explaining these guidelines.

Related

Calculate the big-O and big-Omega of the following piece of code

I was asked to find the big-O and Big-Omega if I know that function f has O(log(n)), Ω(1) and function g has O(n), Ω((log(n))^2)
for (int i = n; i >= 0; i/=2)
if (f(i) <= g(i))
for (int j = f(i)*f(i); j < n; j++)
f(j);
The big problem that I have is that I don't know how to incorporate the complexity of the funstions in the calculation. I mean I know how to calculate the complexity of loops that looks like this:
for(int i =0 ; i< n*2; i++) {
....
}
or like this
for(int i = 0; i < n; i++) {
for(int j = 0; j < n; j++) {
}
}
Thank you in advance.
This is what I've tried:
for (int i = n; i >= 0; i/=2)// this is aproximatly O(log(n))
if (f(i) <= g(i))// because O(n) < O(log(n)) this line is O(n)
for (int j = f(i)*f(i); j < n; j++)// O(n*log(n))
f(j);// O(log(n))
So by my calculation I get O(log(n)*n *n *log(n)*log(n))=O(n^2*log^3(n))
This is tricky question, because the loop execution depends on values, returned by functions f and g. However remember, that you need to estimate the worst case - so you need to assume two things:
f(i) <= g(i) is always true, so the internal loop always executes
the internal loop starts from 0, because it's a minimal value, which you can get as a result of squaring the f(i) value
So, your piece of code becomes much simpler:
for (int i = n; i >= 0; i/=2)
{
f(i);
g(i);
f(i);
f(i);
for (int j = 0; j < n; j++)
f(j);
}
I think you can take over from here.

How to calculate this radix sorting algorithm complexity?

I have this following code. I need to calculate this algorithm complexity but i have no idea where to start. This algorithm has 3 nested loops so i guess its complexity is n^3 or am i wrong?
public static void RadixSort(DataArray data)
{
IList> digits = new List>();
for (int i = 0; i < 10; i++)
{
digits.Add(new List<int>());
}
for (int i = 0; i < data.Length; i++)
{
for (int j = 0; j < data.Length; j++)
{
int digit = (int)((data[j] % Math.Pow(10, i + 1)) / Math.Pow(10, i));
digits[digit].Add((int)data[j]);
}
int index = 0;
for (int k = 0; k < digits.Count; k++)
{
IList<int> selDigit = digits[k];
for (int l = 0; l < selDigit.Count; l++)
{
data.Swap(index++, selDigit[l]);
//data[index++] = selDigit[l];
}
}
for (int k = 0; k < digits.Count; k++)
{
digits[k].Clear();
}
}
}
Calculating complexity is more complex than just look at the number of nested loops. If you have a triple nested loop like this:
for(int i=0; i<n; i++)
for(int j=0; j<n; j++)
for(int k=0; k<n; k++)
it will be O(n³), assuming n is not changing in the loop. However, if you consider your case:
for(int i=0; i<n; i++)
for(int j=0; j<m; j++)
for(int k=0; k<m; k++)
the time complexity will instead be O(m²n).
And even the simplest sorting algorithms, like bouble sort, selection sort and insertions sort is O(n²), so if your implementation is worse than that you're doing something wrong. The time complexity for radix sort is O(wn), where w is a measure of the size of the elements.
When uncertain about complexity, a reasonable approach is to add counters to the inner-loop code and at the end of the routine print out the counts. Next, vary the size of the input to see how the results change. The empirical results can immediately confirm or deny your analytic or intuited results.

Algorithmic big o order of growth code

I'm doing an online course and i'm stuck on this question. I know there are similar questions but they don't help me.
What is the order of growth of the worst case running time of the
following code fragment as a function of N?
int sum = 0;
for (int i = 0; i*i*i < N; i++)
for (int j = 0; j*j*j < N; j++)
for (int k = 0; k*k*k < N; k++)
sum++;
I thought that the order would be n^3 but I don't think this is correct because the loops only go through a third of n each time. So would that make it nlogn?
Also
int sum = 0;
for (int i = 1; i <= N; i++)
for (int j = 1; j <= N; j++)
for (int k = 1; k <= N; k = k*2)
for (int h = 1; h <= k; h++)
sum++;
I think this one would be n^4 because you have n * n * 0.5n * 0.5n
The loops in fact only go up to the cube root of N. (i^3 < n, etc.)
The 3 nested loops of this length, give O(cube root of N, cubed). This O(N)
Of note, if you were correct and they each went to one third of N, then cubing this still gives O(N^3/9), 1/9 is constant, so this is O(n^3)
If you examine the value of sum for various values of N, then it becomes pretty clear what the time complexity of the algorithm is:
#include <iostream>
int main()
{
for( int N=1 ; N<=100 ; ++N ) {
int sum = 0;
for (int i = 0; i*i*i < N; i++)
for (int j = 0; j*j*j < N; j++)
for (int k = 0; k*k*k < N; k++)
sum++;
std::cout << "For N=" << N << ", sum=" << sum << '\n';
}
return 0;
}
You can then draw your own conclusions with greater insight.

Complexity of a triple for loop

for(I = 0; I < n; I++)
for(j = I; j < n; j++)
for(k = I; k < n; k++)
statement;
outer loop runs n times.
2nd loop runs (n - I) times = n(n-1)/2 times.
3rd loop runs (n- I) times = n(n-1)/2 times.
so statement will run (n(n-1)/2)^2 times.
Is this correct?
You can count like this to check whether it is right or not
int Cnt = 1; // initialization
for(I = 0; I < n; I++)
for(j = I; j < n; j++)
for(k = I; k < n; k++, Cnt++)
printf ("This is the %dth time\n", Cnt);
It is O(n^3) - because
O(n^3+AnyConst*n^2+AnyOtherConst*n+ThirdConst)=O(n^3)
O notation estimates asymptotic behavior as n goes to infinity, therefore, only fastest growing component matters.

What will be the complexity of for loop if nothing is happening in the body of loop

Code:
int c = 0;
for (int i = 0; i < n; i++)
{
for (int j = 0; j < n; j++)
{
c = i * j;
}
}
Time Complexity: O(n2)
Now what will be the complexity of following code:
for (int i = 0; i < n; i++)
{
for (int j = 0; j < n; j++)
{
//c = i * j;
// nothing is happening inside the loop
}
}
whether complexity will be same as above( O(n2) ) or something else??
Theoretically - yes because there is still the issue of increasing the i and j which still needs to happen, and comparing them to the end value in each iteration.
However - compilers might optimize it to be done in constant time, and just set the post values of i and j.
For both complexity is O(N^2).

Resources