Can someone help me find the worst case big-O runtime of the following algorithm in terms of n?
// precondition: A contains only positive numbers
public int[] four(int A[])
{
int n=A.length;
int[] B = new int[n];
int max;
for (int k=n-1; k >= 0; k--) {
max = findMax(A); //call to findMax above
B[k]=A[max];
A[max]=-1;
}
return B;
}
// precondition: A contains only positive numbers
public int[] four(int A[])
{
int n=A.length; //constant operation
int[] B = new int[n]; //constant operation
int max; //constant operation
for (int k=n-1; k >= 0; k--) { //iterates through n times
max = findMax(A); //call to findMax above //will take complexity of O(n) assuming A is scrambled,
B[k]=A[max]; //constant operation
A[max]=-1; //constant operation
}
return B; //constant operation
}
This entire operation will take O(n^2) time as the loop is ran O(n) times with an operation inside that takes the time complexity of O(n) to complete assuming findmax() will take O(n) which is usual in the case that A[] is a scrambled array
This itself looks to be selection sort using 2 arrays.
The complexity of your code depends on the complexity of findMax().
As you algorithm counts one time from n-1 to 0, the time-complexity is O(n⋅f(n)), where f(n) is the complexity of findMax().
A is assumend to be an unsorted, since you are sorting it. So findMax() is probably a linear search with a complexity of O(n).
So the overall complexity would be O(n²).
Related
I'm trying to solve this algorithm but I'm not sure
here is the code(trying to get the complexity)
For (i =0, i<N, i++) {
For (j=0, j<i/2, j++) {
S.O.P (“”);
}
}
the S.O.P stands for the instructions given to the CPU.
I don't know what S.O.P. stands for, but for the sake of the question, I'll suppose it takes a fixed amount of time - O(1).
Therefore, the only thing left is defining the time the for loops take to run.
for (i =0, i<N, i++) { // n times
For (j=0, j<i/2, j++) { // for each time, this runs n/2 times
S.O.P (“”); // fixed time O(1)
}
}
Given that, we can calculate:
T(n) = {sum for i from 0 to n} i/2 = (1/2)*(n*(n-1)/2)
T(n) = (n*(n - 1)/4) * O(1) = O(n^2/4) = O(n^2)
So the final time complexity would be O(n^2) (O of n squared).
Question 1
public void guessWhat1(int N){
for (int i=N; i>0, i=i/2){
for (int j=0; j<i*2; j+=1){
System.out.println(“Hello World”);
}
}
}
The first loop will run for log(n).
The second loop will run for log(n).
The upper bound is O(log^2(n). What would be Big Θ?
Question 2
public void guessWhat2(int N) {
int i=1, s=1;
while (s<=N) {
i += 1;
s = s + i;
}
}
The upper bound for this is O(n). I am not quite sure about the Big Θ.
It would great if someone could clarify on these. Thank You
Lets get clear with the definitions of the notations first.
Big O: It denotes the upper bound of the algorithm.
Big Theta: It denotes the average bound of the algorithm.
For your first question
public void guessWhat1(int N){
for (int i=N; i>0, i=i/2){
for (int j=0; j<i*2; j+=1){
System.out.println(“Hello World”);
}
}
}
For i=N, inner loop runs 2N times, i=N/2 inner loop runs for N times, for i=N/4 inner loop runs for N/2 times.....
so the total complexity = O(2N+N+N/2+N/4+...+1)
which is equal to O(N(2+1+1/2+1/4+....1/N))= O(N(3+1/2+1/4+....1/N))
N(3+1/2+1/4+....1/N)
= N( 3 + 1 - (0.5)^logN ) = O(N(4-1/N)) = O(N)
So the complexity is O(N), even in theta notation its the same N as the above loops takes the same time for all cases.
For your second question
public void guessWhat2(int N) {
int i=1, s=1;
while (s<=N) {
i += 1;
s = s + i;
}
}
The while loop takes O(sqrt(N)). Same as above, here also the theta notation will also be the same as big O notation, which is sqrt(N).
The theta notation varies from big O if input has multiple cases. Lets take an example of insertion sort https://en.wikipedia.org/wiki/Insertion_sort where N is the size of the input array. If the input array is already sorted it takes linear time, but if the input array is reverse sorted it takes N^2 time to sort the array.
So in that case for insertion sort, the time complexity is O(N^2).
For best case it is theta(N) and for worst case its theta(N^2).
I was going through an article on analysis of time complexity of loops at a very popular website(link given below) and according to that article the time complexity of below loops 1st and 2nd are O(1) and O(n) respectively.
But i think the time complexity of both loop is same O(n)
for (int i = 1; i <= c; i++) {
// some O(1) expressions
}
My reasoning : `c*n=O(n)
after going through answers below , My reasoning is wrong as there is no varying input n. the loop run is fixed- c times. hence irrespective of the input value n , the loop will run constant time. so O(1) complexity
for (int i = 1; i <= n; i += c) {
// some O(1) expressions
}
My reasoning : c*n=O(n)
Am i missing something ?I would be grateful if someone can help and explain
This is the link of the article : http://www.geeksforgeeks.org/analysis-of-algorithms-set-4-analysis-of-loops/
A loop or recursion that runs a constant number of times is also
considered as O(1).
Here: C is a constant value. So basically, you are performing constant number of operation irrespective of the value of n
// Here c is a constant
for (int i = 1; i <= c; i++) {
// some O(1) expressions
}
Also in Second Loop:
for (int i = 1; i <= n; i += c) {
// some O(1) expressions
}
Your reason c*n = O(n) is not correct. Here
Increment by C. For n elements, loops occur n/c which is asymptotically O(n/c) ~ O(n)
for (int i = 1; i <= c; i++) { // some O(1) expressions }
Here c is a constant. So basically, you are performing constant number of operation irrespective of the value of n. That is why is it considered as constant complexity, O(1).
for (int i = 1; i <= n; i += c) { // some O(1) expressions }
You are looping with a input value n, which is essentially variable with the given input to the program or algorithm. Now the c is again a constant, which will remain same for all the different values of n. The complexity is considered as O(n).
for (int i = 1; i <= n; i++) { // some O(1) expressions }
This is same as the above only, just that value of the c is 1.
All the complexities are represented in asymptotic notation format. Constant factors are removed because they will be same irrespective of the value of n.
1) There is no n in the picture, i dunno why you think it O(n). The loop is going from 1 to c, so its O(c), and as c is a constant, the complexity is O(1).
2) The loop starts from 1 and goes till n, incrementing c at every step. Clearly the complexity is O(n/c), which asymptotically is O(n).
O(1) : The complexity of this loop is O(1) as it runs a constant amount of time c.
// Here c is a constant
for (int i = 1; i <= c; i++) {
// some O(1) expressions
}
O(n): The complexity of the loop is O(n) if it is incremented or decremented by constant amount. For example, these loops have O(n) time complexity.
// Here c is a positive integer constant
for (int i = 1; i <= n; i += c) {
// some O(1) expressions
}
for (int i = n; i > 0; i -= c) {
// some O(1) expressions
}
I've computed complexity of below algorithm as
for i = 0 to m
for j = 0 to n
//Process of O(1)
Complexity: O( m * n)
This is simple example of O( m * n). But I'm not able to figure out how O(m+n) computed. Any sample example
O(m+n) means O(max(m,n)). A code example:
for i = 0 to max(m,n)
//Process
The time complexity of this example is linear to the maximum of m and n.
for i=0 to m
//process of O(1)
for i=0 to n
//process of O(1)
time complexity of this procedure is O(m+n).
You often get O(m+n) complexity for graph algorithms. It is the complexity for example of a simple graph traversal such as BFS or DFS. Then n = |V| stands for the number of vertices, m = |E| for the number of edges, where the graph is G=(V,E).
The Knuth-Morris-Pratt string-searching algorithm is an example.
http://en.wikipedia.org/wiki/Knuth%E2%80%93Morris%E2%80%93Pratt_algorithm#Efficiency_of_the_KMP_algorithm
The string you're looking for (the needle or the pattern) is length m and the text you're searching through is length n. There is preprocessing done on the pattern which is O(m) and then the search, with the preprocessed data, is O(n), giving O(m + n).
The above example you have is a nested for loop, when you have nested loops and have 2 different inputs m and n ( considered very large in size). The complexity is said to be multiplicative. so for first for loop you write complexity O(m) and for inner for loop you write O(n) and as they are nested loop, you can write as O (m) * O(n) or O(m * n).
static void AddtiviteComplexity(int[] arr1,int[] arr2)
{
int i = 0;
int j = 0;
while (i < arr1.Length)
{
Console.WriteLine(arr1[i]);
while (j < arr2.Length)
{
Console.WriteLine(arr2[j]);
j++;
}
i++;
}
}
similarly when have 2 loops and they are not nested and have 2 different inputs m and n ( considered very large in size), the complexity is said to be additive.
For the First loop, you write the complexity O(m) and for the second loop you write the complexity O(n) and as there are separate loops, you can write the complexity as O(m) + O(n) or O(m + n).
static void AddtiviteComplexity(int[] arr1,int[] arr2)
{
int i = 0;
int j = 0;
while(i< arr1.Length)
{
Console.WriteLine(arr1[i]);
i++;
}
while (j < arr2.Length)
{
Console.WriteLine(arr2[j]);
j++;
}
}
Note: the above code is for example with int array is example purpose. Also I have used while loop, it doesn't matter if it's a while or a for loop for calculating complexity.
Hope this helps.
Why does the below function have a time complexity of O(n)? I can't figure it out for the life of me.
void setUpperTriangular (
int intMatrix[0,…,n-1][0,…,n-1]) {
for (int i=1; i<n; i++) {
for (int j=0; j<i; j++) {
intMatrix[i][j] = 0;
}
}
}
}
I keep getting the final time complexity as O(n^2) because:
i: execute n times{//Time complexity=n*(n*1)
j: execute n times{ //Time complexity=n*1
intMatrix[i][j] = 0; //Time complexity=1
}
}
The code iterates through n^2/2 (half a square matrix) locations in the array, so its time complexity is O(n^2)
This is same as insertion sort's for loop. Time complexity of insertion sort is O(n2).
So, CS department head explained it a different way. He said that since the second loop doesn't iterate n times, it iterates n! times. So technically it is O(n).
It can be at most considered as O(n.m) which finally comes down to O(n.n) or O(n^2)..