Big O - Don't understand time complexity for these algorithms? - java

I am learning how to do time complexity in school and the professor uploaded some examples. For the first example below, the answer is supposed to be O(n^3) but I do not understand how.
public static int fragment1 (int n)
{
int sum = 0;
for (int i = 1; i <= n*n; i++)
for (int j = 0; j*j < i; j++) sum++;
return sum;
} // end fragment1
When I attempt the problem I look at the first for loop and see that it runs n^2 times, then the inner for loop is also n^2. When added up I get O(n^4).
public static int fragment5 (int n)
{
int sum = 0;
for(int i=0; i < n*n*n; i++)
{
if(i%(n*n) == 0) {
for(int j=i*i; j > 0; j--)
sum++;
} // if
else
{
for(int k=0; k < i: k++)
sum++;
} // else
} // outer loop
}
For the problem above, the answer should be O(n^7). When I attempted it I got: first for loop runs n^3 times, inner for loop n^3*n^3 = n^6, and the for loop inside the else statement I get n with my final answer being O(n^10). Can someone give me tips on the above problem? I feel clueless when it comes to this one and I have been getting the other problems right so far.

One of the basic assumptions when calculating BigO is to drop non dominant terms.
Using the first example,
Outer Loop has order O(n^2)
Inner Loop has order O(n^3)
The inner loop independently runs for 'n' times but because it is nested, it will run for 'n * (n^2)
'
So, the BigO is of the form O((n^2) + (n^3)) which would suffice to O(n^3).
You can try using the same technique for the second problem.
If you still have some confusion, have a look at the following video:
Big O Notation

Related

How do you calculate T(n) in an equation from a code fragment?

I'm having trouble converting code fragments into equations that figure out T(n) of said equation. An example code fragment is this:
a = b + c;
d = a + e;
This specific questions asks to determine T(n). How would I go about doing that? Another example code given is as follows:
sum = 0;
for (i=0; i<3; i++)
for (j=0; j<n; j++)
sum++;
I've attempted to follow instruction and examples from other questions that are similar, but am getting stuck on how the equation is found exactly. Here's an example and result that I know of so far:
Code:
sum = 0;
i = 1;
while (i <= N)
{
sum = sum + 1;
i++;
}
With the result being this:
T(N) = 2 + (Σ with N on top and i+1 on bottom) * 2
and that ends up simplifying to 2+2N
I'm unsure of how this result is found though.
Here is how you can approach this problem:
sum = 0; // 1 - O(1)
for (i=0; i<3; i++) // This will run 3x times - O(3)
for (j=0; j<n; j++) // This will run n times (O(n)), meaning the sum will be increased n times
sum++;
Then you can write T(n)=1+3*(1+n+2n)≈1+3n. This means that the time complexity for this code is O(n).
Generally, when looking at the simple for loop, like the one here, you can determine its complexity by looking at the condition statement. For j<n the complexity will be O(n), and for i<3 the complexity will be O(3).

For loops computation in loop header

int k;
for (int i = 1; i < 10; i++) {
k = 2*i-1;
System.out.print(k+" ");
}
How would I write the above statement with the computation done in the header? I can't seem to figure out the syntax..
So I'm going to answer your question and suggest one minor improvement which moves k into the proper scope of the loop:
for(int i = 1, k = 2*i - 1; i < 10; i++, k = 2*i - 1) {
System.out.println(k+" ");
}
I'm also tending to agree with the comments. You probably should just leave the computation of k inside the loop body for readability's sake. You can still put the declaration of k in the header if k is not needed outside of the scope of the loop.

The code after my for loop doesn't execute

I have a short program that creates an array of integers and removes non-primes:
public class Main {
public static void main(String[] args){
int[] nums = new int[100];
for (int i = 0; i < nums.length; ++i){
nums[i] = i + 1;
}
int j = 0;
while(j < nums.length){
System.out.print(nums[j]);
System.out.print(" ");
j++;
}
for (int n = 1; n < nums.length / 10; n++){
for (int p = n; p < nums.length; p += nums[n]){
if(p > n){
nums[p] = 0;
System.out.println("p"+nums[p]);
}
}
}
//this code doesn't execute
System.out.println("x");
}
}
The statement which is supposed to simply print "x" doesn't execute, nor does any other statement I put after the for loop. The program does not enter an infinite loop, so what's going on? I feel like this is something obvious that I'm just missing.
Edit: it was an infinite loop, I just didn't realize it.
In your p loop, on the second iteration, p > n is true and you set nums[p] to 0. From that point forward, p will never increase, because your incrementer is p += nums[n] and nums[n] is 0, and so your loop never terminates.
This sort of problem is best solved by using a debugger. Using a debugger is a fundamental skill for a programmer. With a debugger, you can step through statements, inspect variables, and see exactly what your code is doing. It's not an advanced technique, it's essential from Day 1 so you can correctly diagnose issues with your code. If you don't currently know how to use a debugger, stop what you're doing and learn to use one, it will be incredibly valuable and time-saving to you. There's almost certainly one built into your IDE.
Are you falling into a infinite loop? In the console press cmd+c or ctrl+c and see what that does. If the program stops it is a sign of a infinite loop.

Worst Case Big O with Java Algorithms

1.
for(i = 0; i < 3; i++){
for(j = 0; j < 10; j++){
print i+j;
}
}
I would assume Big O would be 30 since the most amount of times would be 3*10.
2.
for(i = 0; i < n; i++){
for(j = 0; j < m; j++){
print i+j;
}
}
Would be O be n*m?
3.
for(i = 0; i < n; i++){
for(j = 0; j < m; j++){
for(int k = 1; k < 1000; k *= 2){
print i+j+k;
}
}
}
n * m * log base 2 (1000) The Big O is in nlog(n) time
4.
for(i = 0; i < n - 10; i++){
for(j = 0; j < m/2; j++){
print i+j;
}
}
5.
for(i = 0; i < n; i++){
print i;
}
//n and m are some integers
for(j = 1; j < m; j *= 2){
print j;
}
Can someone give me a hand with this if you know Big O. I am looking at these and at a loss. I hope I am posting this in the right location, I find these problems difficult. I appreciate any help.
I think it's important just to point out that Big O notation is all about functions that, given an arbitrary constant, will be considered upper bounds at some point.
O(1)
This is because each loop iterates in a constant amount of time. We would refer to this as O(1) instead of O(30) because the function which is the upper bound is 1 with an arbitrary constant >=30.
O(n*m)
Simply because we have to loop through m iterations n times.
O(n*m)
This is the same as the previous one, only we're throwing in another loop in the middle. Now you can notice that this loop, similar to the first problem, is just a constant time. Therefore, you don't even need to really spend time figuring out how often it loops since it will always be constant - it is O(1) and would be interpreted as O(n*m*1) which we can simply call O(n*m)
O(n*m)
For the outer loop, don't get caught up on the .. - 10 and realize that we can just say that loop runs in O(n). We can ignore that .. - 10 for the same reason we ignored the exact values in the first problem; constants don't really matter. This same principle applies for the m/2 because you can think of m just being manipulated by a constant of 1/2. So we can just call this O(n*m).
T(n) = O(n) + O(lg m) => O(n + lg m)
So there are two components we have to look at here; the first loop and the second loop. The first loop is clearly O(n), so that's no problem. Now the second loop is a little tricky. Basically, you can notice that the iterator j is growing exponentially (notably power of 2's), therefore that loop will be running the inverse of exponentially (logarithmic). So this function runs in O(n + lg m).
Any constant factor can be ignored. O(30) is equal to O(1), which is what one would typically say for 1).
2) Just so.
3) in O(n*m*log_2(1000)), log_2(1000) is constant, so it's O(n*m).
4) O(n-10) is same as O(n). O(m/2) is same as O(m). Thus, O(n*m) again.
5) Trivially O(n).
6) O(log_2(m)).

Java modulus operator and PreIncrement - SCJA

Im revising for my SCJA exam at the minute and im confused by this question and answer. The question is what is the result of running and compiling the code.
public class Test{
public static void main(String args[]){
int counter = 0;
for(int i=0; i< 4; ++i){
for(int k=0; k< 4; ++k){
system.out.println("Hello - "+ ++counter);
if((k % 4) == 0)
break;
}
}
}
}
So the answer they give is "Hello-1" because 0 % 4 = 0
But my question is should k not be 1 because its been pre-incremented?
Thanks in advance!
A for loop has the following structure:
for (initialization; condition; update)
The update is executed after every execution of the loop.
Therefore the following two loops are identical:
for (int i = 0; i < 10; i++) {
and
for (int i = 0; i < 10; ++i) {
my question is should k not be 1 because its been pre-incremented?
The ++k happens at the end of the loop iteration, i.e. after the if statement.
It makes no difference whether it's ++k or k++; in either case the first value of k is zero.
So the answer they give is "Hello-1"
This is clearly incorrect, since counter is never incremented and stays at zero throughout the program.
k cannot be 1.
This is because when a for loop runs, it only updates after it has executed all the code within the loop. Since the loop breaks even before the first iteration is completed, k remains 0.

Categories