What would be the time complexity be of these lines of code?
Begin
sum = 0
For i = 1 to n do
For j = i to n do
sum = sum + 1
End
I want to say O(n) = 2n^2 + 1 but I'm unsure because of the i=j part.
Your answer is correct!
A nested loop instinctively leads you to the right answer which is O(n^2). In doing Big-O analysis, it usually doesn't matter being specific to the point i.e. saying the time complexity is O(2n^2) or O(3n^2 + 1) -- saying O(n^2) is enough since that is the dominating task of the function.
The i = j condition simply makes it so that there are...
i=1: n operations
i=2: (n-1) operations
...
i=n: 1 operation
So, the sum of all operations you do is 1 + 2 + ... n = n(n+1)/2 which is O(n^2).
Related
I am thinking about how to correctly calculate time complexity of this function:
def foo(lst):
jump = 1
total = 0
while jump < len(lst):
for i in range(0, len(lst), jump):
total += i
jump = jump * 2
return total
I assume that it's O(n) where n is length of list.
Our while loop is O(n) and for loop is also O(n), that means that we got 2*O(n) which equals O(n).
Am I right?
Your calculation have mistakes, for nested loop we multiply the complexity of outer loop with the complexity of inner loop to get the full complexity.
If n is the length of list then the while loop runs log(n) time as every time we are using jump = jump * 2
Inner loop is like, n/1 times when jump = 1, and n/2 times when jump is 2, so the complexity of inner loop is like : (n/1) + (n/2) + (n/4) + (n/8) .... till logn times
Hence total time complexity = n(1 + 1/2 + 1/4 + 1/8 +ā¦ till logn). The coefficient of n here is negligible, so the complexity is O(n)
start = 0
while (start!= len(array)-1):
for i in range(start +1,len(array)):
if (array[i]<array[start]):
array[i],array[start] = array[start],array[i]
print(array)
start += 1
in this case should'nt the complexity be like
O(n) = n * [(n-1) + (n-2) + .... (n-(n-1))]
as for each of the n times of the outer loop the inner loop runs for diff steps gradually reducing by one. In this way O(n) comes to be (n^3 - n^2)/2. What is wrong with my approach.?enter code here
Look at that in this way. The first time (start=0) the inner loop performs n-1 steps,
the second time (start=1) the inner loop performs n-2 steps, and so on. Thus you have:
(n-1) + (n-2) + ... + 1 steps, which is equals to (n^2-n)/2 steps.
The outer loop executes n times while the inner loop executes ? So the total time is n*something.
Do i need to learn summation,if yes then any book to refer?
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j+=i)
printf("*");
This question can be approached by inspection:
n = 16
i | j values | # terms
1 | 1, 2, ..., 16 | n
2 | 1, 3, 5, ..., 16 | n / 2
.. | .. | n / 3
16 | 16 | n / n
In the above table, i is the outer loop value, and j values show the iterations of the inner loop. By inspection, we can see that the loops will take n * (1 + 1/2 + 1/3 + ... + 1/n) steps. This is a bounded harmonic series. As this Math Stack Exchange article shows, there is no closed form for the above expression in terms of n. However, as this SO article shows, there is an upper bound of O(n*ln(n)).
So, the running time for your two loops is O(n*ln(n)).
I believe the time complexity of that is O(n*log(n)). Here is why:
Let us pick some arbitrary natural number i and see how many steps the inner loop takes for this given i. Well for this i, you are going from j=1 to j<=n with a jump of i in between. So basically you are doing this summation many steps:
summation = 1 + (1+i) + (1+2i) + ... (1+ki)
where k is the largest integer such that 1+ki <= n. That is, k is the number of steps and this is what we want to solve for. Well we can solve for k in the equality resulting in k <= (n-1)/i and thus k = ā(n-1)/iā. That is, k is the floor function/integer division of (n-1)/i. Since we are dealing with time complexities, this floor function doesn't matter so we will just say k = n/i for simplicity. This is the number of steps that the inner loop will take for a given i. So we basically need to add all these for i = 1 to i <= n.
So numsteps will be this addition:
numsteps = n/1 + n/2 + n/3 + ... n/n
= n(1 + 1/2 + 1/3 + ... 1+n)
So we need to find the sum of 1 + 1/2 + ... 1/n to finish this. There is actually no good closed form for this sum but it is on the order of ln(n). You can read more about this here. You can also guess this since the integral from 1 to n of 1/x is ln(n). Again, since we are dealing with time complexity, we can just use ln(n) to represent its complexity. Thus we have:
numsteps = n(ln(n))
And so the time complexity is O(n*log(n)).
Edit: My bad, i was calculating the sum :P
im also having trouble finding omega(), and theta() as appropriate
x=0;
for k=1 to n
for j=1 to n-k
X=X+1;
The inner loop is n-1 + n-2 + n-3 ... + 1 + 0. Use this tutorial on calculating the sum of an arithmetic series to find the solution. The outer loop is obviously just "n."
This will be the big-theta. The big-oh will be the same as big-theta when you pull off everything but the first term and remove the multiplier, e.g. Theta(2*log(n) + 5) becomes O(log(n)). Omega is the same as big-Oh in this case, because the best case and worst case are identical; or you can cheat and say that big-Omega is constant time, because the big-Omega of EVERY function is constant time.
First, look at your boundaries. k=1 and k=n.
For k=1, the inside loop is executed (n-1) times.
For k=n the inside loop is execured (0) times.
So, 0 + 1 + ... + (n-1) is an arithmetic sum => (n-1)(n)/2 times.
Now, test it on a few small values :)
the answer is like this :
n-1 + n -2 + n -3 + ... = n*n - (1+2+3+ ... + n) = n^2 - n(n-1)/2
I just wanted to make sure I'm going in the right direction. I want to find a max value of an array by recursively splitting it and find the max of each separate array. Because I am splitting it, it would be 2*T(n/2). And because I have to make a comparison at the end for the 2 arrays, I have T(1).
So would my recurrence relation be like this:
T = { 2*T(n/2) + 1, when n>=2 ;T(1), when n = 1;
and and therefore my complexity would be Theta(nlgn)?
The formula you composed seems about right, but your analysis isn't perfect.
T = 2*T(n/2) + 1 = 2*(2*T(n/4) + 1) + 1 = ...
For the i-th iteration you'll get:
Ti(n) = 2^i*T(n/2^i) + i
now what you want to know for which i does n/2^i equals 1 (or just about any constant, if you like) so you reach the end-condition of n=1.
That would be the solution to n/2^I = 1 -> I = Log2(n). Plant it in the equation for Ti and you get:
TI(n) = 2^log2(n)*T(n/2^log2(n)) + log2(n) = n*1+log2(n) = n + log2(n)
and you get T(n) = O(n + log2(n) (just like #bdares said) = O(n) (just like #bdares said)
No, no... you are taking O(1) time for each recursion.
How many are there?
There are N leaves, so you know it's at least O(N).
How many do you need to compare to find the absolute maximum? That's O(log(N)).
Add them together, don't multiply. O(N+log(N)) is your time complexity.