Big O complexity of nested loop - big-o

What could be the big O of this code?
I thought --> n + n/2 + n/3 + .....+1 which is just n, but also looks like O(n^2)
public int sums(int n){
int sum = 0;
for (int i = 1; i < n; i++) {
for (int j = 0; j < n/i; j++) {
sum++;
}
}
return sum;
}

This will be O(n log n).
n + n/2 + n/3 + ... + 1 = n (1 + 1/2 + 1/3 + ... 1/n),
where (1 + 1/2 + 1/3 + ... 1/n) ~ O(log n).
Reference: https://www.quora.com/What-is-the-sum-of-the-series-1-frac-1-2-frac-1-3-frac-1-4-frac-1-5-up-to-infinity-How-can-it-be-calculated/answer/Avinash-Sahu-7

In general, nested loops fall into the O(n)*O(n) = O(n^2) time complexity order, where one loop takes O(n) and if the function includes loops inside loops, it takes O(n)*O(n) = O(n^2).
Similarly, if the function has ‘m' loops inside the O(n) loop, the order is given by O (n*m), which is referred to as polynomial time complexity function.

Related

Find time complexity of a given nested loop

What is the time complexity for this loop below?
int sum = 0;
for(int n = N; n > 0; n/=2)
for(int i = 0; i < n; i++)
sum++
I figured out that the inner loop runs N + N/2 + N/4 + N/8 + ... + 1 times, but now I don't know how to proceed. How do I get the tilde or big-O from this loop?
Thanks in advance.
Big-O from this loop is O(N) such as the dependence of the number of iterations on N is linear.
About 1/2 + 1/4 + 1/8 + ... https://en.wikipedia.org/wiki/1/2_%2B_1/4_%2B_1/8_%2B_1/16_%2B_%E2%8B%AF
About Big-O https://www.khanacademy.org/computing/computer-science/algorithms/asymptotic-notation/a/big-o-notation
N + N/2 + N/4 + N/8 + ... + 1 forms a GP(geometric progress) which sums up to 2N. While defining time complexity in terms of big O, we discard the constant. So time complexity of your problem is O(N).

Time complexity of nested for loop with inner iteration variable dependent on the outer one

This is the loop structure :
for (int i = 1 ; i < n ; i++) {
for (int j = 0 ; j < n ; j += i) {
// do stuff
}
}
My guess was O(nlogn) as it clearly cannot be O(n^2) since the increment in j is increasing and it clearly cannot be O(n sqrt(n)) since the increment is not that high. But I have no idea how to prove it formally.
Each time complexity of the inner loop is based on the value of i is n/i. Hence, total time would be n + n/2 + n/3 + ... + n/n = n(1+1/2+1/3+...+1/n).
As we know 1+1/2+1/3+...+1/n is a harmonic sereis and asymptotically is log(n). Hence, the algorithm is run in O(nlog(n)).

Time complexity of following code with explanation?

What is the time complexity of this algorithm, and why?
int count = 0;
for (int i = N; i > 0; i /= 2) {
for (int j = 0; j < i; j++) {
count += 1;
}
}
The correct answer is O(n), but I am getting O(nlogn). Can anyone tell me why it's O(n)?
On the first iteration, the inner loop executes N times, and then N/2 times, and then N/4 times, and so on. This can be expressed as an infinite sum:
N + N/2 + N/4 + N/8 + N/16 + N/32 + ...
If you factor out the N from each term, you get:
N * (1 + 1/2 + 1/4 + 1/8 + 1/16 + 1/32 + ...)
The infinite sequence in parentheses converges on the value 2 (more info on Wikipedia). Therefore, the number of operations can be simplified to:
N * 2
In terms of Big-O, the asymptotic value is within:
O(N)
You can check this by observing that the relationship in the output between N and count is linear: Ideone Demo

Big-O complexity of algorithms

I'm trying to figure out the exact big-O value of algorithms. I'll provide an example:
for (int i = 0; i < n; i++) // 2N + 2
{
for (int x = i; x < n; x++) // N * 2N + 2 ?
{
sum += i; // N
}
} // Extra N?
So if I break some of this down, int i = 0 would be O(1), i < n is N+1, i++ is N, multiply the inner loop by N:
2N + 2 + N(1 + N + 1 + N) = 2N^2 + 2N + 2N + 2 = 2N^2 + 4N + 2
Add an N for the loop termination and the sum constant, = 3N^2 + 5N + 2...
Basically, I'm not 100% sure how to calculate the exact O notation for an algorithm, my guess is O(3N^2 + 5N + 2).
What do you mean by exact? Big O is an asymptotic upper bound, so it's by definition not exact.
Thinking about i=0 as O(1) and i<n as O(N+1) is not correct. Instead, think of the outer loop as doing something n times, and for every iteration of the outer loop, the inner loop is executed at most n times. The calculation inside the loop takes constant time (the calculation is not getting more complex as n gets bigger). So you end up with O(n*n*1) = O(n^2), quadratic complexity.
When asking about "exact", you're running the inner loop from 0 to n, then from 1 to n, then from 2 to n, ... , from (n-1) to n, each time doing a constant time operation. So you do n + (n-1) + (n-2) + ... + 1 = n*(n+1)/2 = n^2/2 + n/2 iterations. To get from the exact number of calculations to big O notation, omit constants and lower-order terms, and you'll end up with O(n^2) (the 1/2 and +n/2 are omitted).
Big O means Worst case complexity.
And Here worst case will occur only if both the loops will run for n numbers of time i.e n*n.
So, complexity is O(n2).

Order of Growth in a for loop

How can I analyze this code fragment to conclude that it is O(N)?
int sum = 0;
for (int i = 1; i < N; i *= 2)
for (int j = 0; j < i; j++)
sum++;
The value of i in the outer loop increases exponentially, you can think of it as increasing a binary digit each time. The number of digits it takes to represent N is log(N). So the outer loop will execute log(N) times The inner loop will execute
2^0 + 2^1 + 2^2 + ... + 2^log(N)
The formula for this geometric series is (updated from Niklas B's comment)
1(1 - 2^log(N))/(1 - 2)
= 2^(log(N) + 1) - 1
~= 2N
Over all the algorithm will be O(2N + log(N))
but for big-O notation, the 2N component will overwhelm log(N) so overall the complexity is O(N)

Resources