What is the time complexity (big O) of this function ? and how to calculate it ?
I think it's O(N^3) but am not sure.
int DAA(int n){
int i, j, k, x = 0;
for(i=1; i <= n; i++){
for(j=1; j <= i*i; j++){
if(j % i == 0){
for(k=1; k <= j; k++){
x += 10;
}
}
}
}
return x;
}
The complexity is O(n^4)
But not because you blindly drop unused iteration.
it's because when you consider all instruction, O(n + n^3 + n^4) = O(n^4)
int DAA(int n){
int x = 0;
for(int i=1; i <= n; i++) // O(n)
for(int j=1; j <= i*i; j++) // O(1+2+...n^2) = O(n^3)
if(j % i == 0) // O(n^3) same as loop j
for(int k=1; k <= j; k++) // O(n^4), see below
x += 10; // O(n^4) same as loop k
return x;
}
Complexity of conditioned inner loop
the loop k only execute when j%i==0, i.e. {i, i*2, i*3 ... i*i}
so for the case the inner-most loop execute, the algorithm is effectively
int DAA(int n){
int x = 0;
for(int i=1; i <= n; i++) // O(n)
for(int t=1; t <= i; t++) // O(1+2+...+n) = O(n^2)
for(int k=1; k <= t*i; k++) // O(n^4)
x += 10;
return x;
}
Why simply drop unused iteration not work?
let's say it's now
int DAA(int n){
int x = 0;
for(int i=1; i <= n; i++) // O(n)
for(int j=1; j <= i*i; j++) // O(1+2+...+n^2) = O(n^3)
if(j == i)
for(int k=1; k <= j; k++)
x += 10; // oops! this only run O(n^2) time
return x;
}
// if(j==i*log(n)) also cause loop k becomes O((n^2)log(n))
// or, well, if(false) :P
Although the innermost instruction only run O(n^2) time. The program actually do if(j==i)(and j++, j<=i*i) O(n^3) time, which make the whole algorithm O(n^3)
Time complexity can be easier to compute if you get rid of do-nothing iterations. The middle loop does not do anything unless j is a multiple of i. So we could force j to be a multiple of i and eliminate the if statement, which makes the code easier to analyze.
int DAA(int n){
int x = 0;
for(int i=1; i <= n; i++){
for(int m=1; m <= i; m++){ // New variable to avoid the if statement
int j = m*i; // The values for which the inner loop executes
for(int k=1; k <= j; k++){
x += 10;
}
}
}
return x;
}
The outer loop iterates n times. O(n) so far.
The middle loop iterates 1 time, then 2 times, then... n times. One might recognize this setup from the O(n2) sorting algorithms. The loop executes n times, and the number of iterations increases to n, leading to O(n×n) complexity.
The inner loop is executed on the order of n×n times (the complexity of the middle loop). The number of iterations for each execution increases to n×n (the maximum value of j). Similar to how the middle loop multiplied its number of executions and largest number of iterations to get its complexity, the complexity of the inner loop – hence of the code as a whole – should become O(n4), but I'll leave the precise proof as an exercise.
The above does assume that the time complexity represents the number of times that x += 10; is executed. That is, it assumes that the main work of the innermost loop overwhelms the rest of the work. This is usually what is of interest, but there are some caveats.
The first caveat is that adding 10 is not overwhelming more work than incrementing. If the line x += 10; is not a convenient stand-in for "do work", then it might be that the time complexity should include all iterations, even those that do no work.
The second caveat is that the condition in the if statement is cheap relative to the innermost loop. In some cases, the conditional might be expensive, so the time complexity should include the number of times the if statement is executed. Eliminating the if statement does interfere with this.
If you happen to fall into one of these caveats, you'll need a count of what was omitted. The modified code omits i2−i iterations of the middle loop on each of its n executions. So the omitted iterations would contribute n times n2−n, or O(n3) towards the overall complexity.
Therefore, the complexity of the original code is O(n4 + n3), which is the same as O(n4).
Related
Say I have a for loop as:
for(int i=0,j=i+1;i<n-1,j<n;j++)
{
//some code
if(condition)
{
i++;
j=i;
}
}
What will be the time complexity and why?
Edited:
void printAllAPTriplets(int arr[], int n)
{
for (int i = 1; i < n - 1; i++)
{
// Search other two elements of
// AP with arr[i] as middle.
for (int j = i - 1, k = i + 1; j >= 0 && k < n;)
{
// if a triplet is found
if (arr[j] + arr[k] == 2 * arr[i])
{
cout << arr[j] << " " << arr[i]
<< " " << arr[k] << endl;
// Since elements are distinct,
// arr[k] and arr[j] cannot form
// any more triplets with arr[i]
k++;
j--;
}
// If middle element is more move to
// higher side, else move lower side.
else if (arr[j] + arr[k] < 2 * arr[i])
k++;
else
j--;
}
}
}
What would be the time complexity of this particular function and why?? #walnut #DeducibleSteak #Acorn .This is the code for "Printing all triplets in sorted array that form AP"
O(n^2) is when you iterate through all the possible values of one variable each time you iterate through the second one. As such:
for(int i=0; i < n; i++){
for (int j = 0; j < m; j++{
//Do some action
}
}
In your example, even though you're using two vars, but it's still a O(n).
Assuming that increasing i by one takes one second, then assigning the new i to j takes one second too, then the complexity is O(2n). Since constant numbers are insignificant when speaking about complexities, then the complexity of your code is still O(n)
The loop you have written does not make sense, because you are using the comma operator and discarding one of the conditions, so it is equivalent to j < n.
Even if the condition gets triggered many times (but a constant number w.r.t. n, i.e. not becoming larger as n grows), then you can easily show you will do <= k*n iterations, which means O(n) iterations.
If that is not true, but the condition is at least side-effect free, then you can only bound it by O(n^2), e.g. as #walnut suggests with j == n - 1 (like in a triangle matrix).
If you allow for side-effects in the condition (e.g. j = 0, with an equals sign), then it can be an infinite loop, so there is no possible bound.
How does the if-statement of this code affect the time complexity of this code?
Based off of this question: Runtime analysis, the for loop in the if statement would run n*n times. But in this code, j outpaces i so that once the second loop is run j = i^2. What does this make the time complexity of the third for loop then? I understand that the first for loop runs n times, the second runs n^2 times, and the third runs n^2 times for a certain amount of times when triggered. So the complexity would be given by n*n^2(xn^2) for which n is the number of times the if statement is true. The complexity is not simply O(n^6) because the if-statement is not true n times right?
int n;
int sum;
for (int i = 1; i < n; i++)
{
for (int j = 0; j < i*i; j++)
{
if (j % i == 0)
{
for (int k = 0; k < j; k++)
{
sum++;
}
}
}
}
The if condition will be true when j is a multiple of i; this happens i times as j goes from 0 to i * i, so the third for loop runs only i times. The overall complexity is O(n^4).
for (int i = 1; i < n; i++)
{
for (int j = 0; j < i*i; j++) // Runs O(n) times
{
if (j % i == 0) // Runs O(n) × O(n^2) = O(n^3) times
{
for (int k = 0; k < j; k++) // Runs O(n) × O(n) = O(n^2) times
{
sum++; // Runs O(n^2) × O(n^2) = O(n^4) times
}
}
}
}
The complexity is not simply O(n^6) because the if-statement is not true n times right?
No, it is not.
At worst, it is going to be O(n^5). It is less than that since j % i is equal to 0 only i times.
The first loop is run n times.
The second loop is run O(n^2) times.
The third loop is run at most O(n) times.
The worst combined complexity of the loop is going to be O(n) x O(n^2) x O(n), which is O(n^4).
Keep in mind that the following pseudo code is similar to c++, so i will use a c++ tag
void matrixmult (int n, const number A[][], const number B[][], number C[][])
{
index i, j, k;
for(i = 1; i <= n; i++) //the i for loop will run n + 1 times
for(j = 1; j <=n; j++) //the j for loop will run n(n+1) times
C[i][j] = 0 //this will run (n-1)n times
for(k = 1; k <=n; k++) //the k for loop will run (n-1)(n+1) times
C[i][j] = C[i][j]+ A[i][k] * B[k][j]; //this will run n((n-1)(n+1))
I was instructed by my professor to find the time complexity function of the very last line of code above
I believe that the time complexity function is T(n) = n(n-1)(n+1)
I need someone to double check my work, did i make a mistake somewhere? did i even get the correct time complexity here?
any help will be appreciated
You have three nested loops, looping n steps each, so it's n^3.
Getting more detailed. Depending on the model of computation, you could instead count the number of assignments, comparisons, multiplications and even memory accesses.
void f(int n)
{
for(int i =1; i<=n; i++){
if(i % (int)sqrt(n)==0){
for(int k=0; k< pow(i,3); k++){
//do something
}
}
}
}
My thinking process:
number of times execute if statement: sum i=1 to n (theta(1)).
number of times execute things inside if: sum i=1 to sqrt(n) (for loop)
number of times execute for loops: sum k=0 to i^3 (theta(1)) = i^3
This will give me: theta(n) + sum i=0 to sqrt(n) (theta(i^3)) = theta(n) + theta(n^2)
which gives me theta(n^2)
The answer key he gave is theta(n^3.5)
I am just wondering if i made any mistake on my thinking process. I have asked my professor twice about this question. Just want to see if there is anything I didn't see before I bother him again.. Thanks!
Using Sigma notation, I came up with the exact closed-form.
Besides, the formula below assumes the process, which doesn't verify the condition that executes the innermost loop, is negligible.
It's up to you to determine tight order of growth bounds, because of flooring function and square root etc.
Further details here: https://math.stackexchange.com/questions/1840414/summation-with-floor-and-square-root-functions-tight-bounds
void f(int n) {
for(int i =1; i<=n; i++){ //--- n times
if(i % (int)sqrt(n)==0){ // --- 2 times (constant)
for(int k=0; k< pow(i,3); k++){ // sqrt(n)^3 and n^3 times
//do something
}
}
}
}
Taking the highest order term it should be Theta(n^3)
Assuming do something is constant
c = do somrthing + plus running cost of single iteration of inner
loop
a = runnning cost of running single iteration of outer most loop
b = running cost of if block Thinking more about it cn^3/2 + cn^3
+ a*n + b*2)
Taking the highest order term Theta(n^3) or
since c is same coefficient for both the n^3 and n^3/2 we can reduce
it
= cn^3 + cn^3/2
= cn^3(n^1/2+1)
~ cn^3 * n^1/2
= cn^3.5
My Computer Science II final is tomorrow, and I need some help understanding how to find the Big-Oh for segments of code. I've searched the internet and haven't been able to find any examples of how I need to understand it.
Here's a problem from our sample final:
for(int pass = 1; i <= n; pass++)
{
for(int index = 0; index < n; index++)
for(int count = 1; count < n; count++)
{
//O(1) things here.
}
}
}
We are supposed to find the order (Big-Oh) of the algorithm.
I think that it would be O(n^3), and here is how I came to that conclusion
for(int pass = 1; i <= n; pass++) // Evaluates n times
{
for(int index = 0; index < n; index++) // Evaluates n * (n+1) times
for(int count = 1; count < n; count++) // Evaluates n * n * (n) times
{
//O(1) things here.
}
}
}
// T(n) = (n) + (n^2 + n) + n^3
// T(n) = n^3 + n^2 + 2n
// T(n) <= c*f(x)
// n^3 + n^2 + 2n <= c * (n^3)
// O(n) = n^3
I'm just not sure if I'm doing it correctly. Can someone explain how to evaluate code like this and/or confirm my answer?
Yes, it is O(n^3). However:
for(int pass = 1; pass <= n; pass++) // Evaluates n times
{ //^^i should be pass
for(int index = 0; index < n; index++) //Evaluates n times
for(int count = 1; count < n; count++) // Evaluates n-1 times
{
//O(1) things here.
}
}
}
Since you have three layer of nested for loops, the nested loop will be evaluated n *n * (n-1) times, each operation inside the most inner for loop takes O(1) time, so in total you have n^3 - n^2 constant operations, which is O(n^3) in order of growth.
A good summary of how to measure order of growth in Big O notation can be found here:
Big O Notation MIT
Quoting part from the above file:
Nested loops
for I in 1 .. N loop
for J in 1 .. M loop
sequence of statements
end loop;
end loop;
The outer loop executes N times. Every time the outer loop executes, the inner loop
executes M times. As a result, the statements in the inner loop execute a total of N * M
times. Thus, the complexity is O(N * M).
In a common special case where the stopping condition of the inner loop is J <N instead
of J <M (i.e., the inner loop also executes N times), the total complexity for the two loops is O(N^2).
Similar rationale can be applied in your case.
You are absolutely correct. It is O(n^3) for your example.
To find the Big Oh running time of any segment of code, you should think about how many times the piece of code does O(1) things.
Let me simplify your example to give a better idea of this:
for(int index = 0; index < n; index++) // Evaluates n * (n+1) times
for(int count = 1; count < n; count++) // Evaluates n * n * (n) times
{
//O(1) things here.
}
}
In the above case, the inner loop runs n times for each run of the outer loop. And your outer loop also runs n times. This means you're doing n things, n number of times. Making it O(n^2).
One other thing to take care of is that Big Oh is an upper bound limit. This means that you should always think about what's going to happen to the code when you have a large input (in your case, a large value of n. Another implication of this fact is that multiplying or adding by constants has no effect on the Big Oh bound. For example:
for(int index = 0; index < n; index++) // Evaluates n * (n+1) times
for(int count = 1; count < 2*n; count++) // Runs 2*n times
{
//O(1) things here.
}
}
The Big Oh running time of this code is also O(n^2) since O(n*(2n)) = O(n^2).
Also check this out: http://ellard.org/dan/www/Q-97/HTML/root/node7.html