Big-O of These Nested Loops - java

I'm pretty new to the Big-O field, so bear with me here. I have been searching about it as much as I could but I still need a lot of work to fully understand it.
I came across these nested for loops in a practicing exercises and there wasn't any solutions and they seem complicated. So, any help would be appreciated.
1)
int sum=0;
for(int i=0; i < n^2; i++) { // n+1
for(int j = n-1; j >= n-1-i; j–-) { // n(n+1)/2 ?
sum = i+j; // n(n+1)/2 ?
System.out.println(sum); // n(n+1)/2 ?
}
}
Big-O = ?
2)
int sum=0;
for(int i=1; i <= 2^n; i=i*2) { // log(n)
for(int j=0; j <= log(i); j++) { // log(n(n+1)/2) ?
sum = i+j; // log(n(n+1)/2) ?
System.out.println(sum); // log(n(n+1)/2) ?
}
}
Big-O = ?
3)
int sum = 0; int k = 23;
for(int i=k; i <= 2^(n−k); i=i*2) { // log(n)
for(int j=2^(i−k); j < 2^(i+k); j=j*2) { // log(log(n)) ?
sum = i+j; // log(log(n)) ?
System.out.println(sum); // log(log(n)) ?
}
}
Big-O = ?
4)
int sum=0;
for(int i=2n; i>=1; i=i/2) {
for(int j=i; j>=1; j=j/2) {
sum = i+j;
System.out.println(sum);
}
}
Big-O = ?
EDIT:
- Corrected #4. Sorry for the mess up.
- Base of the log is 2.
- The ^ here means "to the power", not xor.

There are plenty questions like "Big-O of nested loops" here on stackoverflow (and answers).
However, you will get an answer from me. But first there is a notation problem:
You tagged this question as java. In the code I see something like 2ⁿ or n². In java this means xor, but I think you meant Math.pow(2,n) instead, so for this answer I will treat it as a power operator.
int sum=0;
for(int i=0; i < n^2; i++) { // outer loop
for(int j = n-1; j >= n-1-i; j–-) { // inner loop
sum = i+j; // inner operations
System.out.println(sum);
}
}
The inner operations runs in O(1), so I just counting how often they are called.
The outer loop runs n² times.
for each i (from the outer loop) the inner loop runs i times.
In total you get 0+1+...+(n²-1)+n² = n²(n²+1)/2. This is in Θ(n⁴).
int sum=0;
for(int i=1; i <= 2^n; i=i*2) { // outer loop
for(int j=0; j <= log(i); j++) { // inner loop
sum = i+j; // inner operations
System.out.println(sum);
}
}
The outer loop runs n times, since 2⋅2⋅2⋅...⋅2 (n times) equals 2n.
The inner loop runs k times for each i=2k (1 ≤ k ≤ n), assuming the base of the logarithm is 2.
In total you get 1+2+3+...+n-1+n = n(n+1)/2. This is in Θ(n²).
int sum = 0; int k = 23;
for(int i=k; i <= 2^(n−k); i=i*2) { // outer loop
for(int j=2^(i−k); j < 2^(i+k); j=j*2) { // inner loop
sum = i+j; // inner operations
System.out.println(sum);
}
}
The outer loop runs m times with m minimal such that k⋅2m > 2n-k holds. This can be written as k⋅2k⋅2m > 2n. k has to be positiv (otherwise the outer loop will run forever). Assuming k is bounded by O(n) (canstants are also in O(n)), m is also bounded by O(n).
The inner loop runs always 2⋅k times, no matter what i or n is. This is in O(1) for a constant k and in O(n) for a k bounded by O(n).
In total you get O(n) for a constant k and O(n²) for a k in O(n).
int sum=0;
for(int i=2n; i>=1; i=i/2) { // outer loop
for(int j=i; j>=1; j=j/2) { // inner loop
sum = i+j; // inner operations
System.out.println(sum);
}
}
The outer loop runs log(n) times just like in case 2 (the other way around)
The inner loop runs j times for (basicly) each power of 2 between 1 and 2n.
Assuming n = 2k (means log(n) = k) you get in total
2k+1+2k+2k-1+...+22+21+20=2k+2-1=4n-1. So this in in O(n). This also holds for n not a power of 2.

Methodically finding a solution for your iterative algorithms using Sigma notation:
Using base 2 for the log below:

Related

What's the big O Notation for the two for loops

I am having a hard time analyzing this piece of code:
public int example(int[] arr){
int n = arr.length, total = 0 ;
for (int i=0; i < n; i++)
for (int j=0; j <= i; j++)
total += arr[j];
return total;
}
These two loops don't have curly braces. I could not analyze the time complexity of them.
I need help in counting the time of operation for both of them.
It is O(n2), since there are two layers of loops. The fact that there aren't curly braces does not matter.
The outer loop is executed O(n) times and the inner loop is executed first once, then twice, up until n times. This is an arithmetic sequence from 1 to n where the common difference is 1. Its sum is therefore
(1 + n) * (n) / 2
= (n^2 + n) / 2
= O(n^2)
That code could be rewritten with curly braces as follows:
for (int i=0; i < n; i++) {
for (int j=0; j <= i; j++) {
total += arr[j];
}
}
First loop is executed O(n) times.
Nested loop is executed O(n) times.
So overall O(n^2).

Time complexity O(N) of nested loops with if-statement: O(N^4)?

I am trying to figure out a tight bound in terms of big-O for this snippet:
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++;
}
}
}
If we start with the inner most loop, it will in worst case run k = n^2 times, which accounts for O(N^2).
The if-statement will be true every time j = m*i, where m is an arbitrary constant. Since j runs from 1 to i^2, this will happen when m= {1, 2, ..., i}, which means it will be true i times, and i can at most be n, so the worst case will be m={1,2, ..., n} = n times.
The second loop should have a worsts case of O(N^2) if i = n.
The outer loop has a worst case complexity of O(N).
I argue that this will combine in the following way: O(N^2) for the inner loop * O(N^2) for the second loop * O(N) for the outer loop gives a worst case time complexity of O(N^5)
However, the if-statement guarantees that we will only reach the inner loop n times, not n^2. But regardless of this, we still need to go through the outer loops n * n^2 times. Does the if-test influence the worst case time complexity for the snippet?
Edit: Corrected for j to i^2, not i.
You can simplify the analysis by rewriting your loops without an if, as follows:
for(int i = 1 ; i <= n ; i++) {
for(int j = 1; j <= i ; j++) {
for(int k = 0 ; k<j*i ; k++ ) {
sum++;
}
}
}
This eliminates steps in which the conditional skips over the "payload" of the loop. The complexity of this equivalent system of loops is O(n4).
I analyse your question in a more straightfroward way
we first start by fix i as a costant,
for example, assume it to be k,
so j=1~k^2, when j=k,2k,3k,...,k^2, assume j to be c*k (c=1~k)
the next loop will be executed c^2 times,
so the complexity for a fix i can be expressed as=>
(1+.....+1)+(1+1+...+2^2)+(1+1+...+3^2)+.....+(1+1+...+k^2)
= O(k^3)
so now we set k to be 1~n, so the total complexity will be O(n^4)

Reducing the number of inner loop iterations in Java for efficiency

This is a mini-challenge from a Java textbook.
Following code can be made more efficient (by reducing the number of inner loop iterations, likely with a continue statement).
/*
Use nested loops to find factors of numbers
between 2 and 100.
In the program, the outer loop runs i from 2 through 100. The inner loop successively tests
all numbers from 2 up to i, printing those that evenly divide i.
*/
class FindFactors {
public static void main (String args[]) {
for (int i = 2; i <= 100; i++) {
System.out.print("Factors of " + i + ": ");
for (int j = 2; j < i; j++)
if ((i%j) == 0) System.out.print(j + " ");
System.out.println();
}
}
}
However I try to "simplify" just adds more steps. Any ideas?
In the inner loop test not all numbers up to i. It is enough if you only test up to half of i
for (int j = 2; j <= i/2; j++)
for (int j = 2; j < i; j++)
Without trying to spoil it, consider a natural number N for which you would calculate the factors. Perhaps you could reduce the amount of numbers you have to check?
Look up factoring integers for more information/different algorithms.
Set the length of the inner loop on the square of the index from the outer loop
Each number the max factor its his square

analysis of algorithm run time

What would the big-O run time be? I'm mostly confused about the while loop run time. I know the run times for both for loops are O(n).
cin >> n >> min >> max;
for(int i = min; i < n; i++) {
for(int j = 1; j < max; j++) {
total = 1;
while(total < n) {
total = total *2;
}
}
}
The progression of target in the while loop is:
1 2 4 8 ... 2^P
You need log(2, n) steps -- i.e. log of n in base 2. That loop is O(log n).
First of all, it looks like you forgot to put braces. I'm your code, as it is, the whole loop is not inside the nested for loops. As it is, we have a pointless nested for loop that just sets total to 1, followed by an independent while loop. The complexity of the first is O((n - min) * max), and the second is O(log(n)). The total time complexity is the sum of these.
Probably what you really meant is this:
for(int i = min; i<n; i++) {
for(int j =1; j< max; j++) {
total = 1;
while(total < n) {
total = total *2;
}
}
}
Here, we have the whole loop inside the nested for loops. The time complexity is the multiple of what we calculated earlier, so O((n - min) * max * log(n)). If min and max are constants, then we can reduce to O(n log n)

O(n log n) Time Complexity Algorithm?

I created this algorithm to find the best trade between 3 numbers. It goes through the program and finds the best day to sell, buy, and profit from stock. I need to explain the algorithm used and how the time complexity is O(n log n) but I have a lot of trouble determining that. I was hoping someone could explain O(n log n) and relate it to the method I have.
Here's my method:
public static Trade bestTrade(int[] a)
{
int lowest = a[0];
int lowestIndex = 0;
int highest = a[a.length - 1];
int highestIndex = a.length - 1;
int profit = 0;
for(int i = 1; i < a.length; i++)
{
if (a[i] < lowest && i < highestIndex)
{
lowest = a[i];
lowestIndex = i;
}
}
for(int i = a.length - 2; i >= 0; i--)
{
if (a[i] > highest && i > lowestIndex)
{
highest = a[i];
highestIndex = i;
}
}
for(int i = 1; i < a.length; i++)
{
if (a[i] < lowest && i < highestIndex)
{
lowest = a[i];
lowestIndex = i;
}
}
if (highestIndex > lowestIndex)
{
profit = highest - lowest;
return new Trade(lowestIndex, highestIndex, profit);
}
return new Trade(lowestIndex, highestIndex, profit);
}
}
This function is of O(n) which is superior to O(n log n) .
In general you just look at the loops, since there is no nested loops and you only have loops which go through all elements of a The function is considered n.
The complexity is O(n), where n the length of array a.
You loop 3 times over a, so the running time is roughly 3n, so it is of the order n: O(n).
Try finding the answer to this by yourself. It will help a lot in the future. Also this looks like a O(N) , I am not sure why you are convinced that it is O(NlogN).
This link might be useful,
http://pages.cs.wisc.edu/~vernon/cs367/notes/3.COMPLEXITY.html
O(n)
It is directly proportional to the number of a.length. Each time the for function is run, it runs through every day of data. If there were a method where the number of processes went up by more than the pure number (nested fors) then it could be O(n log n) or O(n^2). But in this case, it's pretty clearly just big O of n.

Categories

Resources