count++;
count++;
count++;
for (int i = 0; i < n; i++)
{
for(int j = 0; j < i*i; j++)
{
for (int k = 0; k < j; k++)
{
count++;
sum++;
}
}
}
count++;
return count;
}
Trying to get the Big O of this coding. Struggling to understand how the loops interact. When I run it, I get n = 25 count = 898960. I've tried O(n)^5+9 all the way to O(n)^5/n
All other examples of this problem don't deal with I is used in the second loop (I*I) and j is used in the third loop
Almost always the best way to compute complexities of kinda loops should be done by making use of sigma notation.
P.S. I don't write necessary +1s in the formulas since it is not important for Big-O notation and doesn't affect max power which is 5.
It looks like it is O(n^5).
for (int i = 0; i < n; i++) // 0 to n -> O(n)
for(int j = 0; j < i*i; j++) // 0 to n * n -> O(n^2) repeated n times -> O(n^3)
for (int k = 0; k < j; k++) // 0 to n * n -> O (n^2) repeated O(n^3) times -> O(n^5)
In the best case scenario, three nested loops would give you O(n^3), but as you have the second loop repeat (n^2) times, that will square its complexity and of the third loop as well. So in a simple mathematical notation that will be: (n) * (n * n) * (n * n) = n^5.
Related
What is the complexity of the given code as a function of the problem size n? Show the details
of your analysis.
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)
}
}
My thoughts so far:
The if statements could not always be true (could be log n)
Nested inner for loops are n^2.
Any help on how to solve it or how to proceed with it would be appreciated.
Thank you.
Without the if(i == n) {} , the number of operation is :
1 + 2 + 3 + 4 + 5 + ... + n*2
= (2n * (2n-1))/2
But at i==n , the number of operations is not i like the rest, it's i².
So the final number of operations is :
((2n * (2n-1))/2) - n + n²
The Big O notation of the above is O(n²)
I have spent so much time trying to find the formula for this code, but still nothing .. I know the running time but the question really is, what if n = 100 for example, how many line of output will this code print? Is there any specific formula to get the count? The code I've done:
int i, j, k;
for (i = 1; i <= n; i++) {
for (j = i + 1; j <= n; j++) {
for (k = j + 1; k <= n; k++) {
System.out.println(i + " " + j + " " + k);
}
}
}
I have a feeling that you are requiring a formula to get number of iteration the nested loops will.
for( i = 1; i <= n; i++ )
for ( j = i+1; j <= n; j++ )
for( k = j+1; k <= n; k++ )
For those loops, the number of iterations will be:
(n*(n-1)*(n-2))/6, where n > 2.
Generic formula for above kind nested loops:
(n*(n-1)* ... *(n-r+1)) / r!, where n > r-1.
Here, r = number of nested loops
For example: when n = 20 and r = 3, number of iterations will be = (20*19*18) / 3! = 1140
Strictly, i < j < k. What's more, 1 ≤ i < j < k ≤ n.
Or in other words, the number of lines printed is the number of different unordered sets of 3 different numbers from a total set of n numbers. You can continue from here.
Hint: combination
I have an algorithm and I need help finding the complexity of it (tightest possible upper bound)
for(int i = 0; i < n/2; i++)
for(int j = 0; j < n/4; j++)
for(int k = 0; k < n; k++)
x++;
My analysis is that if n would not be divided in each for loop, it would be O(n^3). This complexity still holds true, since each "for loop" will reduce each operation to a O(log n) complexity since it divides n every time the loop executes, making it smaller and smaller (smaller than O(n) at least).
I would say that the answer is between O(log n) and O(n^3). Could you help me getting the tightest possible bound?
start with inner loop :
for(int k = 0; k < n; k++)
x++;
is obviously O(n).
now one layer above that :
for(int j = 0; j < n/4; j++)
is O(n) because it takes n/4 for j to reach the n and we know that O(n/4) = O(n)
and like this for outer loop is O(n).so the complexity is O(n^3) because you have three nested loop each with O(n) and non of them have effect on each other.
Assume each step takes time C.
For k-loop, time taken is Cn.
For j-loop, time taken to complete iteration is (Cn)n/4=C(n^2)/4
For i-loop, time taken to complete iteration is (C*(n^2)/4)n/2=C(n^3)/8
So Total time taken=(C/8)*(n^3)
As C/8 is a constant it can be ignored when considering Big-O Notation.
Thus, Time Complexity=O(n^3).
for(int i = 0; i < n/2; i++) --> n/2
for(int j = 0; j < n/4; j++) --> n/4
for(int k = 0; k < n; k++) --> n
x++;
Hence total complexity is O((n^3)/8) which is O(n^3)
public static void complexityexample(int n) {
int count = 0;
int k = 1;
for (int i = 0; i < n; i++) {
for (int j = 0; j < k; j++) {
count++;
}
k *= 2;
for (int t = 0; t < n; t++) {
count++;
}
System.out.println(count);
}
}
Can anyone write me the answer?
for example , I know that nuber of operations in the for loop is 2N+2,
and number of operations in count++; is N
but what for the other parts.
Time complexity is O(2n). The bottle neck is :
for(int j = 0; j < k; j++){
count++;
}
Since k increases exponentially every iteration of i.
In the i'th iteration, k = 2i-1. This means iterating all values from j to k is O(k) = O(2i).
Now, sum it all up for all iterations:
20 + 21 + 22 + ... + 2n-1 = 2n - 1
Where last equality comes from sum of geometric series
Note that the next inner loop:
for (int t = 0; t < n; t++) {
is not influencing the time complexity (in terms of asymptotic notation), since it adds O(n) time for each iteration of i, and this gets quickly suppressed by the exponential behavior of the first inner loop.
If you want to count the value of count at the end, it is the summation of the first inner loop, which as said is (2n)-1, and the second inner loop, which is sum{n | for each i} = n2.
(2^n)+(n*n)
as them main loop is
for (int i = 0; i < n; i++) {
2^n from :
for (int j = 0; j < k; j++) {
count++;
}
and n*n from:
for (int t = 0; t < n; t++) {
count++;
}
1st row ) 1 operation.
2st row ) 2 operations.
3rd row ) 1+n+1+n = 2N+2.
4 ) 2N+2
5)N
7) N
9)2N+2
10)N
13)1
Is this right.
And after all math calculations the final result is : 14N^2 + 22N + 11 - operations.
A precise methodology using Sigma notation would be:
Empirically verified:
When n = 10, number of overall iterations is 1123.
When n = 25, number of overall iterations is 33555056.
When n = 50, it took for ever to execute (I had to change variables type from int to long).
Indeed, this non polynomial algorithm is expensive.
I implemented the Sieve of Eratosthenes in Java, from pseudocode:
public static void sieveofEratosthenes(int n) {
boolean numArray[];
numArray = new boolean[n];
for(int i = 0; i < n; i++)
numArray[i] = true;
int a = 0;
for(int i = 2; i < Math.sqrt((double)n); i++) {
if(numArray[i]) {
for(int j = (int)Math.pow(i, 2); j < n; a++) {
numArray[j] = false;
j += (a * i);
}
}
}
for(int i = 2; i < n; i++) {
if(numArray[i])
System.out.println(i);
}
}
The output it gives me, when i is 15:
2
3
5
7
8
11
12
13
14
Why are some of these values incorrect? I believe my error is in how I define and use the bool array. Thanks!
for(int j = (int)Math.pow(i, 2); j < n; a++) {
numArray[j] = false;
j += (a * i);
}
should read
for(int j = (int)Math.pow(i, 2); j < n; j+=i) {
numArray[j] = false;
}
How SoE works is that it takes each number and "deletes" all numbers following it that are divisible by it. So basically each number x + k*x where k > 0. This can be done by simply adding x to the initial x^2 and then adding iteratively x to it. Here:
for(int j = (int)Math.pow(i, 2); j < n; a++) {
numArray[j] = false;
j += (a * i);
}
You are not adding x but a*x, so you will skip some numbers as a is being incremented (so you will remove 4,6,10,16 etc, see the pattern? it adds 2,4,6 etc to the initial value) so you should stick with:
for(int j = (int)Math.pow(i, 2); j < n; j+=i) {
numArray[j] = false;
}
The problem is at line
j += (a * i);
In loop, this statement gradually multiplies the j by a*i and add it with j.So replace above line with,
j = (a * i);
It will work.
And yes,initialize
a=2
because we don't want numarray[0] or numarray[1] to initialize or use.
Do comment if any query. Thanks
This doesn't directly address your question, but since it's already been answered, I don't see any point in repeating it. Looking at your code, though, I suggest using integer multiplication instead of Math.pow and Math.sqrt to get slightly better performance such as:
for(int i = 2; i*i < n; i++) {
if(numArray[i]) {
for(int j = i*i; j < n; j += i) {
numArray[j] = false;
}
}
}
Admittedly these calls will only be made once per iteration of the outer loop, so the improvement may not be very dramatic. But, calling Math.pow and Math.sqrt are likely to be much more compute intensive than a single integer multiplication. Also, if Java performs sufficiently sophisticated optimization, i*i may only get computed once and used in both places saving even more compute cycles. There's also no risk of integer overrunning in this case since i*i is bounded above by the integer n.