Time Complexity Analysis of the Given Code - time

How do I find time complexity as a function of the problem size n?
sum = 0;
if (EVEN(n)) {
for (i = 0; i < n; i++) {
if (i % 2 == 0) {
O(logn)
}
else {
sum++;
}
}
}
else {
sum = sum + n;
}

The answer is: O(N log N)
Considering the worst case scenario EVEN(n), the for loop will execute N times or in O(N) time.
The worst case complexity of the code inside the for loop is O(log N).
You then multiply the for loop's complexity with the complexity of its contents.
Therefore, O(N) * O(log N) = O(N log N).
EDIT: With regards to the code inside the for loop...
Since the O(log N) execution is only run when i % 2 == 0, that means it only runs every other iteration of the for loop. Therefore, the true complexity is O(0.5log N), but since you drop all constants when calculating complexity, the complexity is still O(log N), and the final answer is still O(N log N).

Related

Time complexity of this code confusing me

I'm struggling to understand the concepts of calculating time complexity. I have this code in C, why does the time complexity is O(n) and not O(n log n)?
The first loop is running for maximum of 3 iteration, the outer for loop is in logarithmic complexity and each iteration of it doing linear time.
int f2 (int n)
{
int j, k, cnt=0;
do
{
++n;
} while (n%3);
for (j=n; j>0; j/=3)
{
k=j;
while (k>0)
{
cnt++;
k-=3;
}
}
return cnt;
}
Why do we neglecting the log time?
T = (n+n/3+n/9+...+1)
3*T - T = 3*n-1
T = 1.5*n-0.5
it's O(n)
It is a common beginner's mistake to reason as follows:
the outer loop follows a decreasing geometric progression, so it iteratess O(log n) times.
the inner loop follows an arithmetic progression, so its complexity is O(n).
hence the global complexity is O(n+n+n+...)=O(n log n).
The mistake is due to the lack of rigor in the notation. The correct approach is
the outer loop follows a decreasing geometric progression, so it iterates O(log n) time.
the inner loop follows an arithmetic progression, so its complexity is O(j) (not O(n) !), where j decreases geometrically.
hence the global complexity is O(n+n/3+n/9+...)=O(n).
The time complexity of you program is O(n).
Because the total number of calculations is : log(n)/log(3) + 2 * (n/3 + n/9 + n/27 + ... < log(n) + n/2 < 2*n

What will be the time complexity of this code?

I've this code :
int arr [];
QuickSort.(arr); // O(log n)
for (int i = 0; i < arr.length() - 1; i++) {
print(i); // O(n)
}
What is the time complexity of this? Is it O(n * log n) or O(n + log n)?
O(log n) + O(n) =
O(n + log n) =
O(n)
In the complexity analysis, you keep the biggest factor only. As n > log n, log n disappears because its growth is negligible when compared to n's when n goes to infinity.
On the other hand, the quicksort algorithm is an O(n²) algorithm, so I guess the real complexity should be:
O(n²) + O(n) =
O(n² + n) =
O(n²)
Where n is the size of the array.

Big(o) notation logn or n?

for(int i = 1; i < N; i = 2*i){
for(j=0; j<i; j++){
}
}
so I just learned that a logN for loop is one that either divides or multiplies in a statement, which the outerloop is doing. However, because the inner loop is incrementing with addition, and that linear time is a higher complexity than logN, would this for loop be considered O(n)?
The inner function is O(n) because it runs in linear time, and the outer function is O(log n) because i is multiplied by 2 every iteration. So to answer you question, yes the inner loop would be considered O(n) because j++ runs in linear time. But since O(n) is higher complexity than O(log n), then O(n) takes more precedence and the overall run time will be O(n).

How does O(log log N) complexity loop look like? [duplicate]

This question already has answers here:
O(n log log n) time complexity
(4 answers)
Closed 7 years ago.
I have a very basic question here
for(int i = 1; i < N/2; i++) {
}
My initial understanding was the time-complexity for the above loop would O(logn) but after reading through some articles it is pretty much evident that it's simply O(n) and O(logn) would look like for (i = 1; i <= n; i *= 2)
Now my question is how does O(log log N) loop look like?
O(log n) loop:
for (i = 1; i <= n; i *= 2)
So you double i at each step. Basically:
Increment => O(n)
Doubling => O(log n)
??? => O(log log n)
What comes after multiplication? Exponentiation. So this would be O(log log n):
for (i = 2; i <= n; i *= i) // we are squaring i at each step
Note: your loop is O(n), not O(log n). Keeping in line with the increment / double / exponentiate idea above, you can rewrite your loop using incrementation:
for(int i = 1; i < n; i += 2)
Even if you increment by more, it's still incrementation, and still O(n).
That loop doesn't look like O(log N). It is what it is, an O(N/2) loop. To quote the definition:
Function f(x) is said to be O(g(x)) iff (if and only if) there exists a positive real number c, and a real number x0 such that |f(x)| <= c|g(x)| for all x >= x0. For example, you could also call that loop O(N), O(N^2), O(N^3) as you can find the required parameters easily. But, you cannot find parameters that will make O(log N) fit.
As for O(log log N), I suppose you could rewrite Interpolation search implementation given here https://en.wikipedia.org/wiki/Interpolation_search to use a for loop. It is O(log log N) on the average!
Your cost is not O(logN) your cost is O(N*logN).
Read the link you will see a function example like :
No matter the number in the beginning of the polynomial cost is the biggest polynomial.
In your case it is
1/2 * n * log(n) , which 1/2 makes no difference your complexity is O(N*logN)

Complexity of O(M+N)

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.

Resources