Can you help me to calculate time complexity of this algorithm? - java

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.

Related

Complexity Analysis that makes every element in the array equal to largest element

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²)

Big O for multi loops

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.

Time complexity optimisation of a "nested for loop" method

I am trying to find the largest differences between indexes of two equal elements, in an zero-index array of integers.
My for loop currently looks like this, with a "nested for loops" structure
which means its time complexity is O(N^2).
Is it possible of reducing its time complexity to O(N * log(N)) or lower?
public static Integer solution(Integer[] arr) {
Integer l = arr.length;
int result = 0;
for (int i = 0; i < l; i++) {
for (int j = 0; j < l; j++) {
if (arr[i] == arr[j]) {
result = Math.max(result, Math.abs(i - j));
}
}
}
return result;
}
I assume you are trying to find the highest difference of two indexes of equal numbers in an array. You don't need to run through the entire array 2 times. The inner loop can simply end at i which will greatly reduce complexity.
public static int solution(int[] arr) {
int l = arr.length;
int result = 0;
for (int i = 0; i < l; i++) {
for (int j = 0; j < i; j++) {
if (arr[i] == arr[j]) {
result = Math.max(result, Math.abs(i - j));
}
}
}
return result;
}
The complexity should just about be O(N * log(N)).

Formula for counting loop iteration

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

Sieve of Eratosthenes - Implementation returning some non-prime values?

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.

Categories