I'm learning how to find t(n) function in java, but this is very confusing and I need help. For example:
for (int k=3; k<n; k++) {
for (int i=2; i<10; i++) {
for (int j=n/2; j<n; j++) {
int a = k*i*j;
System.out.println(a);
}
}
}
Would the T(n) function be:
T(n) = 3(4(n+1) +n)+3(3(not sure)+n)+ 4()+1
With
3(4(n+1) +n)
3= 3 steps for this line of code
4= representing k=3
N+1= representing k
+n= representing k++
and then:
3(3(not sure what goes here for i<10)+n)
firs 3= 3 steps
next 3= representing i=2
+n= representing i++
How does this work exactly?
and what would be the notation for the remaining lines?
Related
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
I have some trouble finding the time complexity of the code below. I figured that the if statement will run for approximately n times; however, I could not manage to describe it mathematically. Thanks in advance.
int sum = 0;
for (int i = 1; i < n; i++) {
for (int j = 1 ; j < i*i; j++) {
if (j % i == 0) {
for (int k = 0; k < j; k++) {
sum++;
}
}
}
}
Outer loop
Well, it's clear that it's O(n) because i is bounded by n.
Inner loops
If we take a look at the second loop alone, then it looks as follows:
...
for (int j = 1 ; j < i*i; j++){
...
j is bounded by i*i or simply n^2.
However, the innermost loop won't be executed for every j, but only for js that are divisible by i because that's what the constraint j % i == 0 means. Since j ~ i*i, there will be only i cases, when the innermost loop is executed. So, the number of iterations in the inner loops is bounded by i^3 or simply n^3.
Result
Hence, the overall time complexity is O(n4).
Question 1.
My Answer: 1 + n^2 * n = n^3
Correct Answer: O(n)
void f(int n) {
if (n<1000000)
return 0;
for (int i=0; i<(n*n); i++)
return f(n-1);
}
Question 2.
My Answer: n * n * logn = n^2*logn
Correct Answer: O(n^3)
int f(int n) {
for (int i=1; i< (n/2); i++)
for(double j =0; j <100; j+= (100.0/n)
doSomething (n/2); //doSomething(m) has time complexity of O(m)
return 0;
}
Question 3.
My Answer: 1 + n * (logn + 1) = O(nlogn)
Correct Answer: O(logn)
int f(n) {
if (n<1) return;
g(n-1);
}
void g(n) {
f(n/2)
doOne(); // doOne has time complexity O(1)
}
Question 1
void f(int n) {
if (n<1000000)
return 0;
for (int i=0; i<(n*n); i++)
return f(n-1);
}
The for loop is not looping at all because the content is a return statement, so you have at most one loop iteration. This means you can can simplify this code to:
void f(int n) {
if (n<=0)
return 0;
return f(n-1);
}
(simplified in regard for the O(n) analysis)
Here you see why it is O(n) because it is counting down until it hit the recursion stop condition. The fact that there is a "high" value check for n<100000 doesn't matter when you call it with something like f(5*10^300);
Question 2
int f(int n) {
for (int i=1; i< (n/2); i++)
for(double j =0; j <100; j+= (100.0/n)
doSomething (n/2); //doSomething(m) has time complexity of O(m)
return 0;
}
In regard for the O(n) analysis you can simplify some lines:
for (int i=1; i< (n/2); i++)
This can be simplified to:
for (int i=1; i<n; i++)
Therefore it's O(n) as already identified by you.
for(double j =0; j <100; j+= (100.0/n)
This can be simplified as:
for(double j =0; j <1; j+= (1.0/n) (divided by 100)
for(double j =0; j <n; j+= 1.0) (multiplied by n)
And again, a simple O(n) loop.
doSomething (n/2);
That is by definition a O(n) statement.
So in total you have O(n)*O(n)*O(n), which is O(n^3).
Question 3
int f(n) {
if (n<1) return;
g(n-1);
}
void g(n) {
f(n/2)
doOne(); // doOne has time complexity O(1)
}
Not sure how you got the O(n*log(n)) here because not every n value is checked. In fact you start at n and the steps are n/2, n/4, n/8, n/16, n/32, n/64, n/128, ... and at some point you reached the terminate condition if (n<1). This is a simple O(log(n)) loop.
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).
i try to find the complexity of this algorithm:
m=0;
i=1;
while (i<=n)
{
i=i*2;
for (j=1;j<=(long int)(log10(i)/log10(2));j++)
for (k=1;k<=j;k++)
m++;
}
I think it is O(log(n)*log(log(n))*log(log(n))):
The 'i' loop runs until i=log(n)
the 'j' loop runs until log(i) means log(log(n))
the 'k' loop runs until k=j --> k=log(i) --> k=log(log(n))
therefore O(log(n)*log(log(n))*log(log(n))).
The time complexity is Theta(log(n)^3).
Let T = floor(log_2(n)). Your code can be rewritten as:
int m = 0;
for (int i = 0; i <= T; i++)
for (int j = 1; j <= i+1; j++)
for (int k = 1; k <= j; k++)
m++;
Which is obviously Theta(T^3).
Edit: Here's an intermediate step for rewriting your code. Let a = log_2(i). a is always an integer because i is a power of 2. Then your code is clearly equivalent to:
m=0;
a=0;
while (a<=log_2(n))
{
a+=1;
for (j=1;j<=a;j++)
for (k=1;k<=j;k++)
m++;
}
The other changes I did were naming floor(log_2(n)) as T, a as i, and using a for loop instead of a while.
Hope it's clear now.
Is this homework?
Some hints:
I'm not sure if the code is doing what it should be. log10 returns a float value and the cast to (long int) will probably cut of .9999999999. I don't think that this is intended. The line should maybe look like that:
for (j=1;j<=(long int)(log10(i)/log10(2)+0.5);j++)
In that case you can rewrite this as:
m=0;
for (i=1, a=1; i<=n; i=i*2, a++)
for (j=1; j<=a; j++)
for (k=1; k<=j; k++)
m++;
Therefore your complexity assumption for the 'j'- and 'k'-loop is wrong.
(the outer loop runs log n times, but i is increasing until n, not log n)