The code fragment below from this link
int[] countingSort(int[] a, int k) {
int c[] = new int[k];
for (int i = 0; i < a.length; i++) //{1}
c[a[i]]++;
for (int i = 1; i < k; i++) //{2}
c[i] += c[i-1];
int b[] = new int[a.length];
for (int i = a.length-1; i >= 0; i--) //{3}
b[--c[a[i]]] = a[i];
return b;
}
It states that the running time is O(n+k) time .k is the range of input
array a .
Can anyone explain why the running time is O(n+k). ?
If we look at the code fragment and see that the {1} for loop runs in n time , {2} runs in K time and the third runs in also n time So total run time should be O(2n+k) time . Is my calculation incorrect? Is the constant 2 ignored here ?
Your calculation is also correct, because O(2n+k) = O(n+k).
For time complexity, only the polynomial degree is important, not the coefficients.
So; O(n) = O(2n) = O(3n) .... = O(xn)
Please read https://en.wikipedia.org/wiki/Time_complexity#Linear_time
Related
static void stableSelectionSort(int[] a, int n)
{
for (int i = 0; i < n - 1; i++)
{
int min = i;
for (int j = i + 1; j < n; j++)
if (a[min] > a[j])
min = j;
// Move minimum element at current i.
int key = a[min];
while (min > i)
{
a[min] = a[min - 1];
min--;
}
a[i] = key;
}
}
What will be the time complexity of Stable selection sort algo? Will it be same as selection sort?
So the outer loop runns n-1 times.The first inner loop from i to n, that is for first time it runs n-1 time then n-2 then n-3 ... 1 . Now for the second loop suppose if all the elements are same then each time the loop would be running from i to 0 , adding both first and second loop the inside loops would be running for n times ,so the worst time complexity would reach n^2
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
what will be the time complexity for the following code?
I calculate it like nĀ²log(n)
int x = 0;
for (int i = 0; i < N; i++)
for (int j = 0; j < N/2; j++)
for (int k = 1; k < N;)
{
x++;
k *= 2;
}
return x;
You are correct!
Number of times the first loop executes = N.
Number of times the second loop executes = N/2.
Number of times the third loop executes = log2(N).
Therefore, time complexity = O(N * (N/2) * log2(N)) = O((N^2)/2 * log2(N)).
After neglecting constants for the highest power of N, time complexity = O((N^2) * log2(N)).
I want to understand the time complexity of my below algorithm, which is an acceptable answer for the famous first missing integer problem:
public int firstMissingPositive(int[] A) {
int l = A.length;
int i = 0;
while (i < l) {
int j = A[i];
while (j > 0 && j <= l) {
int k = A[j - 1];
A[j - 1] = Integer.MAX_VALUE;
j = k;
}
i++;
}
for (i = 0; i < l; i++) {
if (A[i] != Integer.MAX_VALUE)
break;
}
return i + 1;
}
Observations and findings:
Looking at the loop structure I thought that the complexity should be more than n as I may visit every element more than twice in some cases. But to my surprise, the solution got accepted. I am not able to understand the complexity.
You are probably looking at the nested loops and thinking O(N2), but it's not that simple.
Every iteration of the inner loop changes an item in A to Integer.MAX_VALUE, and there are only N items, so there cannot be more than N iterations of the inner loop in total.
The total time is therefore O(N).
What would be the time complexity for the following code snippet?
int[][] A = new int [n][];
for (int i=0; i<n; i++) {
if (i % 2 == 0) // i is a multiple of 2
A[i] = new int [n];
else
A[i] = new int [1];
}
for (int i=0; i<A.length; i++)
for (int j=0; j<A[i].length; j++)
sum = sum + A[i][j];
I understand the first for loop loops n times, then, there will be n/2 rows of of matrix of at length n, and n/2 of at length 1. Would the total time be n^2?
Yes, the complexity will be O(n2).
How?
Half of the times (i.e. n/2 times), you will iterate through n elements = (n/2) * n = n2/2.
Half of the times (again, n/2 times), you will have only one element to iterate over = (n/2) * 1 = n/2.
Therefore, overall complexity = O(n2/2 + n/2) = O(n2)
Well firstly let's decide with terminology. For example, let's put that every single operation will be to equal to 1. Let's take your code (just to be consistent - we will call this method) and go line by line.
int[][] A = new int [n][];
this will be equal to 1.
for (int i=0; i<n; i++) {
Here we have loop and in worst case it will be n.
if (i % 2 == 0) // 1
A[i] = new int [n]; // 1
else
A[i] = new int [1]; // 1
}
Above operation could be counted as 1 each.
for (int i=0; i<A.length; i++)
Loop is equal to n-elements.
for (int j=0; j<A[i].length; j++)
Inner loop is the same n.
sum = sum + A[i][j];
Again this will be equal to 1.
Inner loops are multiplied so you are correct, but take into account that this will be exactly big-O notation O(n2).