This question is unlikely to help any future visitors; it is only relevant to a small geographic area, a specific moment in time, or an extraordinarily narrow situation that is not generally applicable to the worldwide audience of the internet. For help making this question more broadly applicable, visit the help center.
Closed 9 years ago.
This question is for revision from a past test paper
just wondering if i am doing it right
work out the time complexity T(n) of the following piece of code in terms of number of operations for a given integer n:
for ( int i = 1; i < n*n*n; i *= n ) {
for ( int j = 0; j < n; j += 2 ) {
for ( int k = 1; k < n; k *= 3 ) {
// constant number C of elementary operations
}
}
}
so far i've come up with n^3 * n * log n = O( n^4 log n)
I'll have a go.
The first loop is O(1) constant since it will always run 3 iterations (1*n*n*n == n*n*n).
for ( int i = 1; i < n*n*n; i *= n )
The second loop is O(0.5n) = O(n).
for ( int j = 0; j < n; j += 2 )
The third loop is O(log n).
for ( int k = 1; k < n; k *= 3 )
Therefore the time complexity of the algorithm is O(n log n).
i think your missing the key point. I don't see anywhere in the question it asking you to work out complexity in terms of Big-Oh. Instead its asking for number of operations for a given integer n.
Here is my solution,
For a given n, the inner loop variable successively takes the following
values: k = 1 ,3^0, 3, 3^2, . . . , 3^(m-1)
Therefore, the inner loop performs C log3n operations for each pair of values of the
variables j and i.
The middle loop variable j takes n=2 values,
And the outer loop variable i takes three values, 1, n, and n^2 for a given n.
Therefor the time complexity of the whole piece of code is equal to T(n) =
3C(n/2)log3n = 1.5Cnlog3n.
You may want to check this, but this is my interpretation of your question.
Related
This question is for revision from a past test paper just needed advice if I on the right track.
Work out the time complexity T(n) of the following piece of code in terms of number of operations for a given integer n:
for ( int k = n; k >0; k /= 3 ) {
for ( int i = 0; i < n; i += 2 ) {
// constant number C of elementary operations
}
for ( int j = 2; j < n; j = (j*j)) {
// constant number C of elementary operations
}
}
So I thought the outer loop would be O(logn), the first inner loop would be O(n) and the second inner loop would be O(logn). Just wanted to know if I had a rough idea and how to move forward from here.
There was recently a question somewhat similar few days ago for which I provided a step-by-step description of complexity analysis: https://stackoverflow.com/a/49093954/926701
The outer loop is indeed O(log3(n))
The first inner loop is indeed O(n)
The second inner loop is O(log2(log2(n)))
Informally, for the second loop, with j(k) the sequence of values taken by the index j of the for loop, we can write:
j(1) = 2, j(2) = j(1)^2 = 4, j(3) = j(2)^2 = 16, ..., j(k) = j(k-1)^2 >= n
=> j(k) = j(k-1)^2 = j(k-2)^4 = ... = j(1)^(2^k) = 2^(2^k)
=> k = log2(log2(n))
Since the number of operations in the inner loops is independent from that of the outer loop, we can multiply the complexity:
T(n) = O(log3(n) * (n + log2(log2(n))))
= O(n.log3(n))
because log2(log2(n)) << n as n -> +Inf.
for(i=0; i<n; i++) // time complexity n+1
{
k=1; // time complexity n
while(k<=n) // time complexity n*(n+1)
{
for(j=0; j<k; j++) // time complexity ??
printf("the sum of %d and %d is: %d\n",j,k,j+k); time complexity ??
k++;
}
What is the time complexity of the above code? I stuck in the second (for) and i don't know how to find the time complexity because j is less than k and not less than n.
I always having problems related to time complexity, do you guys got some good article on it?
especially about the step count and loops.
From the question :
because j is less than k and not less than n.
This is just plain wrong, and I guess that's the assumption that got you stuck. We know what values k can take. In your code, it ranges from 1 to n (included). Thus, if j is less than k, it is also less than n.
From the comments :
i know the the only input is n but in the second for depends on k an not in n .
If a variable depends on anything, it's on the input. j depends on k that itself depends on n, which means j depends on n.
However, this is not enough to deduce the complexity. In the end, what you need to know is how many times printf is called.
The outer for loop is executed n times no matter what. We can factor this out.
The number of executions of the inner for loop depends on k, which is modified within the while loop. We know k takes every value from 1 to n exactly once. That means the inner for loop will first be executed once, then twice, then three times and so on, up until n times.
Thus, discarding the outer for loop, printf is called 1+2+3+...+n times. That sum is very well known and easy to calculate : 1+2+3+...+n = n*(n+1)/2 = (n^2 + n)/2.
Finally, the total number of calls to printf is n * (n^2 + n)/2 = n^3/2 + n^2/2 = O(n^3). That's your time complexity.
A final note about this kind of codes. Once you see the same patterns a few times, you quickly start to recognize the kind of complexity involved. Then, when you see that kind of nested loops with dependent variables, you immediately know that the complexity for each loop is linear.
For instance, in the following, f is called n*(n+1)*(n+2)/6 = O(n^3) times.
for (i = 1; i <= n; ++i) {
for (j = 1; j <= i; ++j) {
for (k = 1; k <= j; ++k) {
f();
}
}
}
First, simplify the code to show the main loops. So, we have a structure of:
for(int i = 0; i < n; i++) {
for(int k = 1; k <= n; k++) {
for(int j = 0; j < k; j++) {
}
}
}
The outer-loops run n * n times but there's not much you can do with this information because the complexity of the inner-loop changes based on which iteration of the outer-loop you're on, so it's not as simple as calculating the number of times the outer loops run and multiplying by some other value.
Instead, I would find it easier to start with the inner-loop, and then add the outer-loops from the inner-most to outer-most.
The complexity of the inner-most loop is k.
With the middle loop, it's the sum of k (the complexity above) where k = 1 to n. So 1 + 2 + ... + n = (n^2 + n) / 2.
With the outer loop, it's done n times so another multiplication by n. So n * (n^2 + n) / 2.
After simplifying, we get a total of O(n^3)
The time complexity for the above code is : n x n x n = n^3 + 1+ 1 = n^3 + 2 for the 3 loops plus the two constants. Since n^3 carries the heaviest growing rate the constant values can be ignored, so the Time complexity would be n^3.
Note: Take each loop as (n) and to obtained the total time, multiple the (n) values in each loop.
Hope this will help !
Basically I am struggling to come to grips with operation counting and Big-O notation. I understand it is possibly one of the harder parts of computer science to understand and I have to admit I am struggling with it. Could anyone give me some help with these examples, and possibly any further help/links with Big-O?
for (i = 0; i < N; i++)
{ for (j = i; j < N; j++)
{ sequence of statements }
}
Here I would say the complexity is O(N²) - Quadratic
int m = -9
for (j = 0; j < n; j+=5)
{
if (j<m)
{
for (k = 1; k <n; k*=3)
{some code}
}
}
Here I would also say is O(N²). The first loop takes N and the second loop takes N so I would say the answer is O(N*N) which is equal to O(N²).
Any help and advice for further understanding would be great!!
The first is indeed O(n^2), as you suspected, assuming the 'sequence of statements' is O(1).
However, the second part of code is O(n), since the condition j < m is never met - and thus, the outer loop only iterates itself without actually doing nothing. The inner loop is not even reachable.
As side note, some compilers may actually optimize the second part of code to run in O(1) by just setting the end values of variables, but this is not the point of the question.
The second example is complexity O(N).
int m = -9
for (j = 0; j < n; j+=5)
{
if (j<m)
{
// this never executes; m is negative and j is positive
}
}
First example:
The inner loop executes N times when i = 0, N-1 times when i = 1, and so on...
You can just calculate the number of steps the for loops execute
(N) + (N - 1) + (N - 2) + ... + 2 + 1
steps = N(N+1)/2 = (N^2 + N) / 2
N <=> 1 |add the left to the right| => N+1
(N - 1) <=> 2 |add the left to the right| => N+1
(N - 2) <=> 3 |add the left to the right| => N+1 . . . N
What does the big-O nation means?
F(N) = O(G(N)) means that |F(N)|<= c*|G(N)| where c > 0
It means that the G(N) function is an upper bound on the grothw rate of the function. F(N) could not grow faster than G(N).
Just to throw this out here: if we assume that the j<-9 clause is a mistake and ignore it, then your second example has two nested loops. However the inner loop is actually multiplying k times 3. So this makes this inner loop O(log n). Which makes the pair of loops O(n log n). I'm not sure this is the answer, but you asked for further understanding, so... you know... maybe that's further.
Ok, also on a further note I would really suggest you to go through a single lecture in the series of introduction of algorithms. Believe me you won't need to look any further.
http://ocw.mit.edu/courses/electrical-engineering-and-computer-science/6-046j-introduction-to-algorithms-sma-5503-fall-2005/video-lectures/
What is the complexity given for the following problem is O(n). Shouldn't it be
O(n^2)? That is because the outer loop is O(n) and inner is also O(n), therefore n*n = O(n^2)?
The answer sheet of this question states that the answer is O(n). How is that possible?
public static void q1d(int n) {
int count = 0;
for (int i = 0; i < n; i++) {
count++;
for (int j = 0; j < n; j++) {
count++;
}
}
}
The complexity for the following problem is O(n^2), how can you obtain that? Can someone please elaborate?
public static void q1E(int n) {
int count = 0;
for (int i = 0; i < n; i++) {
count++;
for (int j = 0; j < n/2; j++) {
count++;
}
}
}
Thanks
The first example is O(n^2), so it seems they've made a mistake. To calculate (informally) the second example, we can do n * (n/2) = (n^2)/2 = O(n^2). If this doesn't make sense, you need to go and brush up what the meaning of something being O(n^k) is.
The complexity of both code is O(n*n)
FIRST
The outer loop runs n times and the inner loop varies from 0 to n-1 times
so
total = 1 + 2 + 3 + 4 ... + n
which if you add the arithmetic progression is n * ( n + 1 ) / 2 is O(n*n)
SECOND
The outer loop runs n times and the inner loop varies from 0 to n-1/2 times
so
total = 1 + 1/2 + 3/2 + 4/2 ... + n/2
which if you add the arithmetic progression is n * ( n + 1 ) / 4 is also O(n*n)
First case is definitely O(n^2)
The second is O(n^2) as well because you omit constants when calculate big O
Your answer sheet is wrong, the first algorithm is clearly O(n^2).
Big-Oh notation is "worst case" so when calculating the Big-Oh value, we generally ignore multiplications / divisions by constants.
That being said, your second example is also O(n^2) in the worst case because, although the inner loop is "only" 1/2 n, the n is the clear bounding factor. In practice the second algorithm will be less than O(n^2) operations -- but Big-Oh is intended to be a "worst case" (ie. maximal bounding) measurement, so the exact number of operations is ignored in favor of focusing on how the algorithm behaves as n approaches infinity.
Both are O(n^2). Your answer is wrong. Or you may have written the question incorrectly.
So, I'm slightly confused by this question on my homework.
for ( int j = 0; j < 2*n; j++){
for ( int k = 0; k < n * n * n; k += 3)
sum++;
}
So I am at this conclusion after a bit of confusion
for( 1, 2n, n)
for( 1/3( 1, 3n, 1)
I have it as 1/3 because it's going up by 3. I'm just not sure if I'm right, we were just introduced to this so I'm sorta lost.
I'm not completely sure that I understand what you are asking... Assuming that the question is what the Big-O notation for this nested loop would be (and assuming that the addition operation is the base operation)
The outer loop is executed 2n times
The inner loop is executed n^3/3 times for each iteration of the outer loop
That means that the inner statement is executed 2n * n^3/3 = (2/3)*n^4. For Big O notation, we ignore the constants, so this nested loop is O(n^4).