I thought the time complexity of the code below is O(n^2) or O(n*logn).
int j = 0;
for(i = 0; i < n; ++i) {
while(j < n && arr[i] < arr[j]) {
j++;
}
}
However, the answer page says it is O(n).
I can't understand why it becomes so.
My (silly) opinions were the following:
The time complexity is O(n^2) since there are two loop running n times. arr[i] < arr[j] may affect the while loop, but it doesn't matter.
The time complexity is O(n*logn) since the while loop may run less than n times because arr[j] can be smaller than arr[i] during the loop. As a result, while loop would run for log(n) times.
Could you explain why was my answer wrong and why the correct time complexity is O(n)?
for(i = 0; i < n; ++i)
Loops n times.
while(j < n && arr[i] < arr[j]) {
j++;
}
Loops up to n times in total. Note that j is only ever incrementing for the entire loop of i, so it being an inner loop doesn't make it a higher order, as it still can only go from 0 to n for the entire set of loops.
So it's O(2n) = O(n)
In general, to understand the flow of something like this, try adding print statements to understand the flow, printing 'i' and 'j' at every point.
In this specific case, you know how many times the outer for loop is triggered, but try to see how many total times j can be incremented. Even though it's inside the for loop, its number of total iterations may be independent.
Related
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).
int Solution::diffPossible(vector<int> &A, int B) {
for (int i = 0; i < A.size(); i++) {
for (int j = i+1; j < A.size(); j++)
if ((A[j]-A[i]) == B)
return 1;
}
return 0;
}
This is the solution to a simple question where we are supposed to write a code with time complexity less than or equal to O(n). I think the time complexity of this code is O(n^2) but still it got accepted. So, I am in doubt please tell me the right answer.
Let's analyze the worst-case scenario, i.e. when the condition of the if-statement in the inner loop, (A[j]-A[i]) == B, is never fulfilled, and therefore the statement return 1 is never executed.
If we denote A.size() as n, the comparison in the inner loop is performed n-1 times for the first iteration of the outer loop, then n-2 times for the second iteration, and so on...
So, the number of the comparisons performed in the inner loop for this worst-case scenario is (by calculating the sum of the resulting arithmetic progression below):
n-1 + n-2 + ... + 1 = (n-1)n/2 = (n^2 - n)/2
^ ^
|_________________|
n-1 terms
Therefore, the running-time complexity is quadratic, i.e., O(n^2), and not O(n).
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.
I have the following algorithm:
for(int i = n; i > 0; i--){
for(int j = 1; j < n; j *= 2){
for(int k = 0; k < j; k++){
... // constant number C of operations
}
}
}
I need to calculate the algorithm's running time complexity,
I'm pretty sure the outer loop runs O(n) times, the middle loop runs O(log(n)) times, and the inner loop runs O(log(n)) times as well, but I'm not so sure about it.
The final result of the running time complexity is O(n^2), but I have no idea how.
Hope someone could give me a short explanation about it, thanks!
For each i, the second loop runs j through the powers of 2 until it exceeds n: 1, 2, 4, 8, ... , 2h, where h=int(log2n). So the body of the inner-most loop runs 20 + 21 + ... + 2h = 2h+1-1 times. And 2h+1-1 = 2int(log2n)+1-1 which is O(n).
Now, the outer loop executes n times. This gives complexity of the whole thing O(n*n).
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