I want to check my understanding of Big-O notation. If I have code:
for(int bound = 1; bound <= n; bound *= 2){
for( int i = 0; i < bound; i++) {
for(int j = 0; j < n; j += 2){
.....Code
}
for(int j = 1; j < n; j *= 2){
......Code
}
}
}
is the Big-O notation for this N3?
Not quite. The outer loop increment is bound *= 2, so that loop is O(log n). The two inner loops (i and the first j loop) are both O(n), so when nested they're O(n2). (You can ignore the j *= 2 inner loop because it's faster than the j += 2 loop and won't significantly contribute to the program's run time.)
Put this all together and the whole program is O(log n * n2).
Related
Here's the code:
for (int i = 0; i < n; i++) {
for (int j = 0; j < n * n; j++) {
for (int k = 0; k < j; k++) {
sum++;
}
}
}
I need to evaluate the Time complexity in Big-O notation of the nested loops above.
Is it just O(n) * O(n) * O(n) + O(1) to make O(n^3)? Or is there more to it?
The most inner loop is executed in quadratic time (not constant), hence it should be O(n) * O(n^2) * O(n^2) = O(n^5).
Here are all the costs:
Most outer loop - O(n)
The second loop - O(n^2) for each element for the outer loop
The most inner loop - O(n^2) for each element for the second loop
for (int i = 0; i < n; i++) -> runs n times.
for (int j = 0; j < n * n; j++) -> runs n² times.
for (int k = 0; k < j; k++) -> runs n² times (k == j == n²)
n * n² * n² = n^5.
sum+++ is an operation of constant runtime (1) and can therefore be ignored.
The second loop isn't O(n), it's O(n^2) by itself.
I'm having trouble figuring out the time equation for a couple small snippets of code.
int sum = 0;
for (int k = n; k > 0; k /= 2)
for (int i = 0; i < k; i++)
sum++;
int sum = 0;
for (int i = 1; i < n; i *=2)
for (int j = 0; j < i; j++)
sum++;
int sum = 0;
for (int i = 1; i < n; i *=2)
for (int j = 0; j < n; j++)
sum++;
They're all very similar as you can see. I'm not looking for an exact answer or anything, I'm just not really sure where to start with the inner loops. It seems like they would all run n times, but they can't all be the same, right? I'm pretty sure all of the outer loops would be log(n) and that the sum++ would just be a constant (1), but I'm not really sure how all of the inner loops are different and how that would change the equation.
The third code snippet is the easiest to analyze. For each outer loop iteration the inner loop will make 'n' iterations. Since the number of outer loop iterations is O(log(n)) the total number of iterations (and the complexity of the third snippet) is O(n*log(n)).
The first two code snippets have the same complexity, just the outer loop iterates in the descending order in the first snippet, and in the ascending order in the second one. So you iterate over all powers of two which are smaller than 'n', and then repeat the inner loop the corresponding number of times. The total number of iterations is
1 + 2 + 4 + ... + 2^k
where k=log2(n). Sum of powers of 2 is 2^(k+1)=2*2^k=2*n. So, the complexity in both cases is O(n).
int sum = 0;
for (int k = n; k > 0; k /= 2)
for (int i = 0; i < k; i++)
sum++;
n + n/2 + n/4 + n/8 + ... + 1 ≈ 2n = Θ(n)
int sum = 0;
for (int i = 1; i < n; i *=2)
for (int j = 0; j < i; j++)
sum++;
1 + ... + n/8 + n/4 + n/2 + n ≈ 2n = Θ(n)
(Well, not exactly ending with n, n/2 etc, but within a factor of 2 of those, so doesn't matter for the complexity class.)
int sum = 0;
for (int i = 1; i < n; i *=2)
for (int j = 0; j < n; j++)
sum++;
n + n + ... + n ≈ log(n) × n = Θ(n log n)
Write a static method printNumbers that takes an integer max as an argument and prints out all perfect numbers that are less than or equal to max.
At first, I kept getting the wrong answer because the inner loop was set to j < max before I changed it to j < i. However, I don't understand why that range would matter, because wouldn't i % j != 0 anyway, even if the range of j were to be larger?
for (int i = 1; i <= max; i++) {
int sum = 0;
for (int j = 1; j < i; j++) {
if (i % j == 0) {
sum += j;
}
}
if (sum == i) {
System.out.print(sum + " ");
}
}
If I changed the inner loop j < max, then printNumbers(6) gives both 1 and 6, but printNumbers(500) gives only 1 and no other number.
If you set j < max in the inner loop, then when j = i, i % j == 0 returns true and skews your result.
This is a good example of a mathematical error to watch out for in coding.
Q2. Consider the following code fragments (a), (b) and (c) where n is the variable specifying data
size and C is a constant. What is the big-Oh time complexity in terms of n in each case? Show all
necessary steps.
(a)
for (int i = 0; i < n; i = i + C)
for (int j = 0; j < 10; j++)
Sum[i] += j * Sum[i];
(b)
for (int i = 1; i < n; i = i * C)
for (int j = 0; j < i; j++)
Sum[i] += j * Sum[i];
(c)
for (int i = 1; i < n; i = i * 2)
for (int j = 0; j < n; j = j + 2)
Sum[i] += j * Sum[i];
1. for (int i = 0; i < n; i = i + C)
2. for (int j = 0; j < 10; j++)
3. Sum[i] += j * Sum[i];
`
Line 1: int i=0, takes constant time of 1 so O(1)
i<n, takes n+1 time so O(n)
i=i+C, takes n time so O(n)
Total time: 1+(n+1)+n= 2n+2
Line 2:
int j=0, takes constant time of 1 so O(1)
j<10, loops through 10 times and takes n time so O(n)
i=i+C, loops through 10 times and takes n time so O(n)
Total time: 1+(10+10)n= 1+20n
Line 3:
Sum[i]=Sum[i]+j*Sum[i];
Addition and Multiplication takes constant time of 2 and plus 1 to store
or assign the value, and it loops through n times.
Total time:3n
T(n)=(2n+2)+(1+20n)+3n= 25n+3 is O(n) right?
I have a question in regards to the time complexity of the below code. I am guessing that the time complexity is, O(n^3) but my friend told me that the time complexity should be O(n^2). However, I am still not convinced with the answer. My stand is that: the first and second for loop would cost O(1/2 n^2) and inner loop would need another some O(n) complexity. Therefore, it is about O(n^3).
for (int i = 1; i <= len; i++) {
for (int j = i + 1; j <= len; j++) {
int mid = (i + j) / 2;
for (int k = i; k <= j; k++) {
dist[i][j] += Math.abs(A[k - 1] - A[mid - 1]);
}
}
}
So you need to find the time complexity of something like this:
for (int i = 1; i <= N; i++) {
for (int j = i + 1; j <= N; j++) {
for (int k = i; k <= j; k++) {
// some O(1) operation
}
}
}
Each of the loops run in O(N), so the complexity is O(N^3). You can also write a simple test program in your language (I wrote in python):
def check(N):
s = 0
for i in xrange(1, N + 1):
for j in xrange(i + 1, N + 1):
for k in xrange(i, j + 1):
s += 1
return s
print [check(i) for i in xrange(1, 10)] // [0, 2, 7, 16, 30, 50, 77, 112, 156]
And checked for a closed form for this sequence. It is ,
which is clearly O(n^3)