Consider finding the total running time as function of n in these two loops:
(1)
q <- 1
while q <= n
p <- 1
while p <= q
p <- p + 1
q <- 2 * q
(2)
q,s <- 1, 1
while s < n
for j <- 1 to s
k <- 1
while k < = j
k <- 2 * k
q <- q + 1
s <- q * q
Going off of what I know I believe:
(1) is theta(n * lg(n)) where n represents time for inner loop, and
lg(n) for the outer loop.
(2) is theta(n * lg(n) * sqrt(n)) where n represents time for the for loop,
sqrt(n) for the outer loop, and lg(n) for the inner while loop.
I am not sure if this is correct. Any advice would be appreciated.
(1):
This is not the correct way to view this, in fact, the inner while-loop does not do "n cycles lg n times", it does q cycles whatever this number may be each iteration!
The correct way to analyze this is saying that the inner while-loop runs q times, and q takes the numbers 1, 2, 4, ... , n (Yes, the out while-loop runs Θ(lg n) times).
Thus the whole running times is:
1 + 2 + 4 + ... + L beware that if n is not a perfect power of 2, it goes up to the largest power less than n. Thus we can say it runs until it hits n (L = Θ(n))
Computing this gives us a geometric progression with lg(n) elements:
1 + 2 + 4 + ... + n = Θ(n)
(2):
Not a final solution, but a hint/kickstart
Your analysis is still wrong by saying the for-loop runs ~n times, this loop simply runs s times, and s is changing with each and every iteration. On iteration t we have s = t^2.
The analysis goes as so:
The for-loop and its inneer while-loop are correlated, j runs from 1-s and the while loop runs lg(j) - they are correlated because j is changed in each of every iteration of the for-loop. But we need to keep in mind that s is changing as-well, and so the for-loop runs s ∈ {1, 4, 9, ..., n}
Related
I want to know the time complexity of a for loop for(i=m;i<=n;i++) where m and n are both variables. I am thinking it will be O(n-m) as the loop is dependent on both values of m and n.
Please guide me !
Explanation
Assuming your loop only executes statements that run in constant time, i.e. O(1), you simply have to count the amount of loop iterations.
Your loop head
for (i = m; i <= n; i++)
will generate iterations with i being m, m + 1, m + 2, m + 3, ... , n - 2, n - 1, n. So from m to n, both ends inclusive.
So exactly n - m + 1 iterations (simple example 2, 3, 4, 5 with 5 - 2 + 1 = 4).
Thus, the asymptotic time complexity is
O(n - m + 1) = O(n - m)
Like you said.
Yes indeed, it is O(n-m+1) since it will start at m and reaches n in the worst-case scenario.
If the the first loop runs for n+1 times.
second loop runs for n(n+1) times.
third loop will run for ??? it has n^2+1 one relation with with with the second loop i guess but how about with the first one
somefunction(n) {
c = 0
for (i = 1 to n*n)
for (j = 1 to n)
for (k = 1 to 2*j)
c = c+1
return c
}
The first loop has O(n**2) iterations.
The second loop has O(n) iterations.
The third loop has O(n) iterations as well, since j is steadily increasing towards n.
(It's a little easier to see if you sum up the number of times c = c + 1 executes for the two inner loops combined. The inner loop runs 2 times for j = 1, 4 for j = 2, ..., and 2*n times for j = n. 2 + 4 + .. + 2*n = O(n**2).)
You can then (loosely speaking) multiply the three values together to get a total bound of O(n**4).
I'm trying to figure out this time complexity:
for(i=0; i<=(n/2)-1; i++){
for (j=i+1; j<=(n/2)-1; j++){
--some O(1) thing--
}
}
The outer loop I understand to be on its own O(n/2.) However with the inner loop as well I can't wrap my brain around how to break down how many times O(1) executes.
If the inner one stared j=0 I could do n/2(inner) * n/2(outer) = O(n^2) time complexity right? However since j depends on i, I'm thinking some type of summation is involved from i+1 to n/2 but i can't figure out how to set it up...
Basically I need help kind of visualizing how many times it loops, and how to set the summation up. Thank you! :)
Assuming that m = n/2. You will see that in inner loop, j will iterater over range m-1, m-2, m-3,... 1. Summing all of that will be 1+2+..+m-1 = (m-1)*m/2 = O(m^2)
Premise
For simplicity, let us call m = n / 2 - 1. The outer loop runs from 0 to m. The inner loop from i + 1 to m.
Iteration counting
We need to count how often the inner statement which you labeled O(1) is executed. That is, how often the inner loop runs in total, as executed by the outer loop. So let us take a look.
The first iteration of the outer loop generates m - 1 iterations of the inner loop. The second generates m - 1, then m - 2, m - 3, m - 4, ..., 2, 1, 0.
That means that the O(1) statement is, in total, executed:
(m - 1) + (m - 2) + (m - 3) + ... + 2 + 1 + 0
That is the sum from 0 up to m - 1
sum_{i = 0}^{m - 1} i
which can be simplified to
(m^2 - m) / 2
Substitute back
Let us now substitute back m = n / 2 - 1, we get
((n / 2 - 1)^2 - (n / 2 - 1)) / 2
After simplifying, this is
n^2/8 - 3n/4 + 1
Big-O
For Big-O, we observe that it is smaller than
n^2 - 0 + n^2
= 2n^2
Which, by definition is O(n^2).
As you see, this bound is also tight. So we also receive Omega(n^2) which also concludes Theta(n^2).
I was asked if what time complexity if this:
What is the time complexity (with respect of n) of this algorithm:
k=0
for(i = n / 2 ; i < n ; i++ ) {
for( j=0 ; j < i ; j++)
k = k + n / 2
}
choices was : a. O(n) b. O(n/2) c. O(n log(n) and d. O(n^2)
can have a multiple answers.
i know the algorithm above is d. O(n^2) but i came with with a. O(n) since it is looking for complexity of n only?.
if you are to have this question. how would you answer it.?? im so curious about the answer.
The answer is O(n²).
This is easy to understand. I will try to make you understand it.
See, the outer for loop block is executed n - n/2 = n/2 times.
Of course it depends whether the number n is even or odd. If it's even then the outer loop is executed n/2 times. If it's odd then it's executed for (n-1)/2 times.
But for time complexity, we don't consider this. We just assume that the outer for loop is executed n/2 times where i starts from n/2 and ends at n - 1 (because the terminating condition is i < n and not i <= n).
For each iteration of the outer loop, the inner loop executes i times.
For example, for every iteration, inner loop starts with j = 0 to j = i - 1. This means that it executes i times (not i - 1 times because j starts from 0 and not from 1).
Therefore, for 1st iteration the inner loop is executed i = n / 2 times. i = n / 2 + 1 for 2nd iteration and so on upto i = n - 1 times.
Now, the total no. of times the inner loop executes is n/2 + (n/2 + 1) + (n/2 + 2) + ... + (n - 2) + (n - 1). It's simple math that this sums up to (3n² - n)/2 times.
So, the time complexity becomes O((3n² - n)/2).
But we ignore the n term because n² > n and the constant terms because for every n they will remain the same.
Therefore, the final time complexity is O(n²).
Hope this helps you understand.
Can someone confirm me that the complexity of this algorithm is O(n^2)?
a = 0
b = 0
c = n
while (b <= c)
{
for (j = b; j<=c; j++)
{
a = j * j -2 * j + 3
}
b = b + 3
c = c + 2
}
The inner loop executes c - b + 1 times. Each execution of the inner loop body a = j * j -2 * j + 3 takes constant (bounded) time (assuming we're dealing with fixed-width integer types, otherwise it would depend on the multiplication algorithm used [and addition, but that's hard to implement in a way that multiplication is faster]), so the execution of the body of the outer loop is O(d) (Θ(d) even), where d = c - b + 1.
The updates of the variables controlling the outer loop
b = b + 3
c = c + 2
decrease the difference c - b by 1 in each execution of the outer loop's body, hence the outer loop is executed n+1 times, and you have a total of O(n²), since
n n+1
∑ (n+2k - (3k) +1) = ∑ j = (n+1)(n+2)/2
k=0 j=1
It even is Θ(n²), unless the compiler optimises and sets all variables to their final values directly.
Answer for original question with typo:
The inner loop
for (j = b; j==c; j++)
will execute either once - when b == c or not at all, so the body of the outer loop is O(1). The updates in the outer loop
b = b + 3
c = c + 2
mean that the difference c-b decreases by 1 each time the loop body is executed, so
b = 0
c = n
while (b <= c)
will execute n+1 times - total: O(n).
b = b + 3
c = c + 2
makes it so that b catches up to c by one each iteration of the outer loop. This implies the outer loop runs n+1 = O(n) times since they are initially n from each other.
The inner loop executes (c - b + 1) times. We know that they are initially n apart, and get closer by 1 each iteration of the outer loop.
Looking at the number of times the inner loop runs, it would look something like: (n, n-1, n-2, ..., 1) and in total
1 + 2 + ... + n = (n)(n+1)/2 = O(n^2)
Each time your outer loop
while(b <= c)
executes, b and c become closer by 1 than before. However, b and c start off at a distance n apart, so your inner for loop starts by executing n+1 times, then it executes n times, then it executes n-1 times, and so forth, until it finally executes 1 time and then your program finishes. Thus your running time is proportional to
(n+1) + n + (n-1) + (n-2) + ... + 1
and you can look up sum of increasing integers formula to see that this summation is equal to
(n+2)(n+1)/2 = O(n^2)
so your running time is O(n^2)