In the following piece of code, f() is any function taking time of Θ(1). The time complexity should be Θ(n4/3), can someone explain why?
for(int i = 1; i ≤ n; i = 2∗i) {
for(int j = 1; j∗j∗j ≤ n; j = j+1) {
for(int k = 1; k ≤ i∗i; k = k + i) {
f();
}
}
}
By my analysis, the first for loop takes Θ(log2 n) time, the second for loop is Θ(n1/3), and the third for loop is Θ(i). So in total we have Θ((log2 n) × n1/3 × i).
Since i can be n, we have Θ((log2 n) × n1/3 × n) = Θ(n4/3 log2 n). Where is my mistake?
Your bound is not tight, because you counted i as Θ(n), but i is not Θ(n) on average. Consider the sequence of values that i takes, and add these up to count the total number of iterations for the inner loop. We can ignore the middle loop over j for now, since it is independent of i and k.
The sequence of values for i is 1, 2, 4, 8, ... up to n. If we say n = 2r for some r, this is a geometric progression with sum 2r+1 - 1, which is about twice as big as n, so it's Θ(n). This counts both the outer and inner loop; the middle loop gives another factor of Θ(n1/3), and hence the overall complexity is Θ(n4/3) as required.
Related
void buzz(int num, int [] a)
{
for(int i=1;i<num;i*=2){
for(int j=0;j<a[i]%num;j++){
print(num);
}
}
}
I understand that the outer for loop runs for log n times. Need help in understanding the complexity of the inner loop and the overall.
Let us assume num = 2^n for simplicity.
The inner loop runs a[i] % num times, which is comprised in range [0, num-1]. The outer loop runs n times so you can conclude O(num.log(num)) = O(n.2^n) worst-case complexity.
For a precise evaluation, let r[i] := a[i] % num. Then the number of print's is
r[1] + r[2] + r[4] + r[8] + ... r[2^(n-1)].
This is n times the average r (for the relevant indexes; the expectation of r could be (num-1)/2)).
For (i=0, i < n, i++) // n+1
{
for(j=0; j < n, j++) // n * (n+1)
{
C[i][j]+ B[i,j]; // n * n
}
}
The instructor said the time function is f(n) = 2n^2 +2n +1
How come it's not 2n^2+ 2n + 2 because both loops run one extra time when i=n and j=n?
Each time we increment i, we check if the new value becomes equal to or greater than n, so we perform the comparison n + 1 times (n times when i <n and an additional comparison when i becomes equal to n). the same thing for j => (n+1) * (n times when i<n).
So, n*n+(n+1)*n+(n+1)=2n^2+ 2n +1
So these are the for loops that I have to find the time complexity, but I am not really clearly understood how to calculate.
for (int i = n; i > 1; i /= 3) {
for (int j = 0; j < n; j += 2) {
... ...
}
for (int k = 2; k < n; k = (k * k) {
...
}
}
For the first line, (int i = n; i > 1; i /= 3), keeps diving i by 3 and if i is less than 1 then the loop stops there, right?
But what is the time complexity of that? I think it is n, but I am not really sure. The reason why I am thinking it is n is, if I assume that n is 30 then i will be like 30, 10, 3, 1 then the loop stops. It runs n times, doesn't it?
And for the last for loop, I think its time complexity is also n because what it does is
k starts as 2 and keeps multiplying itself to itself until k is greater than n.
So if n is 20, k will be like 2, 4, 16 then stop. It runs n times too.
I don't really think I am understanding this kind of questions because time complexity can be log(n) or n^2 or etc but all I see is n.
I don't really know when it comes to log or square. Or anything else.
Every for loop runs n times, I think. How can log or square be involved?
Can anyone help me understanding this? Please.
If you want to calculate the time complexity of an algorithm, go through this post here: How to find time complexity of an algorithm
That said, the way you're thinking about algorithm complexity is small and linear. It helps to think about it in orders of magnitude, then plot it that way. If you take:
x, z = 0
for (int i = n; i > 1; i /= 3) {
for (int j = 0; j < n; j += 2) {
x = x + 1
}
for (int k = 2; k < n; k = (k * k) {
z = z + 1
}
}
and plot x and z on a graph where n goes from 1 -> 10 -> 100 -> 1000 -> 10^15 or so, you'll get an answer which looks like an n^2 graph. When analyzing algorithmic complexity you're primarily interested in maximum the number of times, in either the worst or most common case, your inputs are looped through omitting constants. So in this case I would expect your algorithm to be O(n^2)
For further reading, I suggest https://en.wikipedia.org/wiki/Introduction_to_Algorithms ; it's not exactly easy but covers this in depth.
I thought the time complexity of the following code is O(log N), but the answer says it's O(N). I wonder why:
int count = 0;
for (int i = N; i > 0; i /= 2) {
for (int j = 0; j < i; j++) {
count += 1;
}
}
For the inners for-loop, it runs for this many times:
N + N/2 + N/4 ...
it seems to be logN to me. Please help me understand why here. Thanks
1, 1/2, 1/4, 1/8... 1/2 ** n is a geometric sequence with a = 1, r = 1/2 (a is the first term, and r is the common ratio).
Its sum can be calculated using the following formula:
In this case, the limit of the sum is 2, so:
n + n/2 + n/4 ... = n(1 + 1/2 + 1/4...) -> n * 2
Thus the complicity is O(N)
Proceeding step by step, based on the code fragment, we obtain:
How do I calculate the time complexity of the following function?
int Compute (int n)
{
int j = 0;
int i = 0;
while (i<=n)
{
i = 2*j + i + 1;
j++;
}
return j-1;
}
Now, I know that the loop has O(n) time complexity, but in this case i grows in a much faster rate. Taking this iteration by iteration I found out that, for every m-th iteration i = m^2. But I'm still confused how to calculate Big-O.
If you look at the values of i and j for a few iterations:
i=1
j=1
i=4
j=2
i=9
j=3
i=16
j=4
and so on. By mathematical induction we can prove that i takes square values: ( 2*n + n^2 + 1 = (n+1)^2 )
Since we loop only while i<=n and since i takes the vales 1, 2^2, 3^2,..., k^2 <=n, it means that we stop when i=k goes over sqrt(n). Hence the complexity seems to be O(k) which means O(sqrt(n)).