How can I tell how many times these nested statements will execute? - algorithm

I have the following pseudocode:
SelectionSort(A)
n = A.length
for j=1 to n-1
smallest = j
for i=(j+1) to n
if A[i] < A[smallest]
smallest = i
exchange A[j] with A[smallest]
I think that the first for-loop test will execute n times, and the nested for-loop will execute 1 + 2 + ... + n = n(n+1)/2 times (please correct me if i'm wrong). But I don't understand how I can tell how many times the nested if-statement will execute? Is it 1/2 * n(n+1)/2 ?

The outer for-loop would run for n times. But, it also holds an inner for-loop which is dependent on the vale of j.
I think that the first for-loop test will execute n times, and the
nested for-loop will execute 1 + 2 + ... + n = n(n+1)/2 times.
The inner for-loop will run (n-1)+(n-2)+...+1 times based on all the iterations of outer for-loop. So, the net iteration of the loop-statements combinedly would be (n-1) + (n-2) + (n-3) + ... + 1 = (n-1)*n/2 = (n2-n)/2 times.
But I don't understand how I can tell how many times the nested
if-statement will execute? Is it 1/2 * n(n+1)/2 ?
As the inner-if statement is dependent on the array elements, it is not possible to directly ascertain exactly how many times it will run.
But, it is for sure that in the worst-case condition,as it is located in the inner for-loop, the maximum number of possible execution(in the worst case) of the if-statement will be (n2-n)/2 times.
So, the worst-case complexity of execution of if-statement is
O(n2)

The outer loop shall run from 1 to n-1, hence n-1 times.
The inner loop shall run from j+1 to n times. This means that when j is 1, it will run from 2 to n times (n-1 times) and when j is n-1, it will run from n to n times (1 time).
Hence the inner loop shall run (n-1 + n-2 + ... + 1) times = n(n-1)/2 times.
The if statement shall execute the same number of times as the inner loop does. Ofcourse the conditional statments shall depend on the result of if conditional.

Related

bubble sort algorithm find time complexity

i am trying to find the time complexity of the bubble sort
n=length[A]
for j <- n-1 to 1
for i <- 0 to j-1
if A[i]>a[i+1]
temp=A[i]
A[i]=A[i+1]
A[i+1]=temp
return A
please any one can help thanks
In line 1 we are assigning length of array to n so constant time
In line 2 we have a for loop that decrements j by 1 every iteration until j=1 and in total will iterate n-2 times.
Inside the first for loop we have a second for loop that increments i by 1 every iteration until i=j-1 and will iterate j-1 times. On each iteration of the inner for loop we have lines 4,5,6,7 which are all just assignments and array access which cost, in total, constant time.
We can think about the two for loops in the following way: For every iteration of the outer for loop, the inner for loop will iterate j-1 times.
Therefore on the first iteration of the outer for loop, we have j = n-1. That means the inner for loop will iterate (n-1)-1 = (n-2) times. Then on the second iteration of the outer for loop we have j= n-2 so the inner for loop will iterate (n-2)-1 = (n-3) times and so on. And we do this until j = 1.
We will then have the equation: (n-2) + (n-3) + ... + 2 + 1 which is the total number of times the inner loop will iterate after the entire algorithm executes. We know that 1 + 2 + ... + n-1 + n = n(n-1)/2 so our expression can be simplified to this: n(n-1)/2 -(n-1) -n = n(n-1)/2 -2n + 1 = O(n^2).
Since our inner for loop will iterate O(n^2) times, and on each iteration do constant work, then that means our runtime will be O(cn^2) where c is the amount of constant work done by lines 4,5,6,7. Combine O(cn^2) with line 1 which is O(1) we have O(cn^2) + O(1) which is just O(n^2).
Therefore runtime of BubbleSort is O(n^2).
If you are still confused then maybe this will help: https://www.youtube.com/watch?v=Jdtq5uKz-w4

Nested Loops Asymptotic analysis

Need help figuring this hw example out guys.
the example states 0(n) running time.
I see that the outter loop is O(logn)
I cant figure out how to describe the inner loop in relation to n.
Help is much appreciated.
for (int i = 1; i <= N; i = i*2) // log n
for (int j = 0; j < i; j++) // less than n i don't know how to describe the growth
sum++;
Answer:: 0(n)
It might be easiest to analyze the runtime of the piece of code in the aggregate. On the first iteration of the outer loop, the inner loop will run 1 time. On the second iteration of the outer loop, the inner loop will run 2 times. On the third iteration of the outer loop, the inner loop will run 4 times. More generally, on the kth iteration of the outer loop, the inner loop will run 2k times. The outer loop stops as soon as i becomes greater than N, which happens after log2 N iterations.
If we sum up the total work done, we'll see that it's
1 + 2 + 4 + 8 + ... + 2log2 N = 2log2 N + 1 - 1 = 2n - 1
(This uses the fact that 1 + 2 + 4 + 8 + ... + 2k = 2k+1 - 1). Therefore, the total work done for the entire piece of code (that is, including both loops) is O(n).
The inner loop is O(n) time because it will go through each element once. If i is 1000, 1000 times, if i is 10000, 10000 times, etc.

Big-O complexity of a piece of code

I have a question in algorithm design about complexity. In this question a piece of code is given and I should calculate this code's complexity.
The pseudo-code is:
for(i=1;i<=n;i++){
j=i
do{
k=j;
j = j / 2;
}while(k is even);
}
I tried this algorithm for some numbers. and I have gotten different results. for example if n = 6 this algorithm output is like below
i = 1 -> executes 1 time
i = 2 -> executes 2 times
i = 3 -> executes 1 time
i = 4 -> executes 3 times
i = 5 -> executes 1 time
i = 6 -> executes 2 times
It doesn't have a regular theme, how should I calculate this?
The upper bound given by the other answers is actually too high. This algorithm has a O(n) runtime, which is a tighter upper bound than O(n*logn).
Proof: Let's count how many total iterations the inner loop will perform.
The outer loop runs n times. The inner loop runs at least once for each of those.
For even i, the inner loop runs at least twice. This happens n/2 times.
For i divisible by 4, the inner loop runs at least three times. This happens n/4 times.
For i divisible by 8, the inner loop runs at least four times. This happens n/8 times.
...
So the total amount of times the inner loop runs is:
n + n/2 + n/4 + n/8 + n/16 + ... <= 2n
The total amount of inner loop iterations is between n and 2n, i.e. it's Θ(n).
You always assume you get the worst scenario in each level.
now, you iterate over an array with N elements, so we start with O(N) already.
now let's say your i is always equals to X and X is always even (remember, worst case every time). how many times you need to divide X by 2 to get 1 ? (which is the only condition for even numbers to stop the division, when they reach 1).
in other words, we need to solve the equation
X/2^k = 1 which is X=2^k and k=log<2>(X)
this makes our algorithm take O(n log<2>(X)) steps, which can easly be written as O(nlog(n))
For such loop, we cannot separate count of inner loop and outer loop -> variables are tighted!
We thus have to count all steps.
In fact, for each iteration of outer loop (on i), we will have
1 + v_2(i) steps
where v_2 is the 2-adic valuation (see for example : http://planetmath.org/padicvaluation) which corresponds to the power of 2 in the decomposition in prime factor of i.
So if we add steps for all i we get a total number of steps of :
n_steps = \sum_{i=1}^{n} (1 + v_2(i))
= n + v_2(n!) // since v_2(i) + v_2(j) = v_2(i*j)
= 2n - s_2(n) // from Legendre formula (see http://en.wikipedia.org/wiki/Legendre%27s_formula with `p = 2`)
We then see that the number of steps is exactly :
n_steps = 2n - s_2(n)
As s_2(n) is the sum of the digits of n in base 2, it is negligible (at most log_2(n) since digit in base 2 is 0 or 1 and as there is at most log_2(n) digits) compared to n.
So the complexity of your algorithm is equivalent to n:
n_steps = O(n)
which is not the O(nlog(n)) stated in many other solutions but a smaller quantity!
lets start with worst case:
if you keep dividing with 2 (integral) you don't need to stop until you
get to 1. basically making the number of steps dependent on bit-width,
something you find out using two's logarithm. so the inner part is log n.
the outer part is obviously n, so N log N total.
A do loop halves j until k becomes odd. k is initially a copy of j which is a copy of i, so do runs 1 + power of 2 which divides i:
i=1 is odd, so it makes 1 pass through do loop,
i=2 divides by 2 once, so 1+1,
i=4 divides twice by 2, so 1+2, etc.
That makes at most 1+log(i) do executions (logarithm with base 2).
The for loop iterates i from 1 through n, so the upper bound is n times (1+log n), which is O(n log n).

Is this algorithm in N^2?

int sum = 0;
for (int i = 1; i <= N; i++)
for (int j = 1; j <= i*i; j++)
sum++;
Is this complexity 1 + 2^2 + 3^2 + 4^2 ... + N^2? How to represent it in big-o notation?
The sum is N(N+1)(2N+1)/6 so your algorithm is O(N^3).
If you expand the sum you have 1/3 * N^3 + ...
You can see it simply by plotting the values of sum after running the algorithm for different values of N:
Straightforwardly, using Sigma notation:
Another way to look at it is to use the "worst case" analysis.
Originally, we have:
The outer for loop will run N times
The inner for loop will run i*i times
This might be confusing since i seems to be changing based on the outer for loop.
However, in the "worst case" scenario, the largest value that i ever attains is N.
Therefore, just substitute N instead of i in our analysis.
Now we have:
The outer for loop will run N times
The inner for loop will run N*N times
And the time complexity of this situation is of course O(N³).
you can always use the intuitive way.
for i = 2 second loop 1 time, first loop 1 time. 1*1
for i = 3 second loop 9 times, first loop 2 times. 9*2
for i = 4 second loop 16 times, first loop 3 times 16*3
for i = 5 second loop 25 times, first loop 4 times. 25*4
.
.
.
you can see the pattern easily. it is (nˆ2)*(n-1) therefore its big o should be O(nˆ3)

time complexity calculation for two for loops with connecting variables

what would be the time coplexity of this:
for(k=1;K<=n;k*=2)
for(j=1;j<=k;j++)
sum++
For this i thought as
1. Outer Loop will run logn times
2. Inner Loop will also run logn times.because i think inner loop j is related to k. So how much ever k runs, same is the running time for j too. So total = O(logn * logn)
but in text they have given total= O(2n-1).
can you please explain
when k is 1 (sum++) runs 1 times
when k is 2 (sum++) runs 2 times
when k is 4 (sum++) runs 4 times
when k is n = 2^k (sum++) runs 2^k times
so we must calculate
1+2+4+ ... + 2^k = 2^0 + 2^1 + 2^2 + .... + 2^k = (1 - 2^(k+1))/(1-2)
because we put n = 2^k so :
k = log(n)
2^(log(n)) = n^(log(2))
2* 2^k -1 = 2*n - 1
This problem is most easily interpreted by forgetting that the outer loop is there and first looking at the inner loop complexity. Suppose that the inner loop runs 'M' times... then the total number of 'sum++' operations will be,
1 + 2 + 4 + ... + 2^(M-1)
This sum can be reduced to '2^(M) - 1' by noticing that this is a binary number composed of all 1's. Now the question is what is M? You've already figure this out, M = log(n)+1 (the +1 is because the loop must run at least once). Plugging this into the inner loop complexity leaves us with,
2^(log(n)+1)-1 = 2*n - 1.
Thus the entire loop scales as O(2n-1). Hope this helps!

Resources