Space complexity of recursive function (Time & Space) - c

There is recursion function below, and I did not calculated time & space complexity. I looked at some resources, but it was not clear enough for me the understanding. Could anyone explain the way of solving in the simplest way, and answers the question?
By the way, I tried to solve time complexity, and I found O(2^n). Is it correct?
int func(int n) {
if (n < 3)
return 3;
else {
return func(n-3)*func(n-3);
}
}

Yes, the time complexity is indeed O(2 ^ n).
The recurrence relation for time complexity is:
T(n) = 2 * T(n - 3)
Applying the above equation k times:
T(n) = 2 * 2 * 2 ... k times * T(n - 3 * k) = 2 ^ k * T(n - 3k)
When k is n/3, T(n) = 2 ^ k = 2 ^ (n / 3) = O(2 ^ n)
There's only one function running at a time and stack depth can be k at max.
So, space complexity is n / 3 or O(n)

Related

find time and space complexity

I need to find the time and space complexity of f3.
I think that g has space complexity of log(n), so for the time complexity, but I am not really sure how I find the time and space complexity of f3 because the calling for g is inside the for commend, does it mean the g is being called every time to check if g(i) < n?
int g(int n)
{
if (n <= 1)
return 1;
return g(n / 2) + 1;
}
int f3(int n)
{
int counter = 0;
for (int i = 0; g(i) < n; ++i)
++counter;
return counter;
}
In short:
Time complexity of f3(n) = O(2^n)
Space complexity of f3(n) = O(n)
Space and Time complexity of g(n) = O(log(n))
Note: (here all log that I refer are log base2 link and all notations are in Big O notation)
Details:
The function "g()" returns floor(log(n))+1. The loop in function "f3()" cotinues until the function 'g()' returns n. For g(i) to return 'n', i needs to be '2^(n-1)'.
In order to terminate the loop in "f3()", 'i' needs to reach 2^(n-1). So 'g()' is called 2^(n-1) times.
So Time complexity of "f3()" = 2^(n-1) x (time complexity of g()) = 2^n x (log n) = O(2^n)
Largest memory used will be during the last call of 'g(i)' where i==2^(n-1).
Therefore space complexity of "f3()" = log(2^(n-1)) = O(n)
As g(n) will run in Theta(log(n)) and each time adds 1 to the final result, the final value of g(i) will be \ceil{log(i)} + 1. On the other hand, the loop inside f3 will run while g(i) < n. It means the loop will iterate up to 2^n. Hence, f3 will run 2^n times. Hence, the time complexity of f3(n) = sum_{i=1}^{2^n} log(i) = log((2^n)!) = \Theta(n * 2^n) (as log((2^n)!) ~ (2^n) log(2^n)).
About space complexity, the maximum depth of g(i), will be when i = 2^n, which is n (n recursive calls). Hence, the space complexity of f3 will be \Theta(n).

what is space complexity for this program?

This is just a test function for calculating space complexity if we consider the
number of stack frames than it will be o(n) but what about those arrays a and b inside for loop and 2-d which will also take some memory in every recursive call,my professor told us that space complexity is size of stack frame but it also consuming some space in that for loop also
Should i consider both that is stack frame and two arrays and 2-d array or give any one of them priority and why?
I am just focusing on space complexity so forget about the result or garbage collection
testfun(n){
if(n==0)
return;
int c[10][10];
int *a=malloc(sizeof(int)*n);
int *b=malloc(sizeof(int)*n);
for(int i=0;i<n;i++)
{ a[i]=n+2*i;
b[i]=n+3*i;
}
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
{
c[i][j]=1;
}
testfun(n-1);
free(a);
free(b);
}
It might be you think about the free function. But, recursion is happened before theese free function. Hence, in each call of the function, depends on the value of the input (i), size of the allocated space is 2i. As the stopping time is on n == 0, the total space complexity is sum_{i = 1}^{n} 2*i = 2*n(n+1)/2 = \Theta(n^2).
The space complexity of the question is O(n)if you have freed the memory locations before call to the function, since each call to the function needs to remember the stack variables.
free(a);
free(b);
test(n - 1);
Else in each function call the function allocates O(n) space and same in subsequent recursive calls as well. So space complexity is O(n^2).
Using Substitution method:
S(0) = 0
S(n) = S(n - 1) + 2n -------- (1)
S(n - 1) = S(n - 2) + 2 (n - 1) -------- (2)
S(n - 2) = S(n - 3) + 2 (n - 2) -------- (3)
Using (1), (2), (3)
S(n) = S(n - 1) + 2n
S(n) = S(n - 2) + 2 (n - 1) + 2n
S(n) = S(n - 3) + 2(n - 2) + 2(n - 1) + 2n
.
.
.
.
S(n) = S(n - k) + 2(n - (k - 1)) + ... + 2n
Let k = n
S(n) = S(n - n) + 2(1) + 2(2) + ... 2(n)
S(n) = S(0) + 2(n * (n + 1)) / 2
S(n) = 0 + n^2 + n
Therefore space complexity is O(n^2).
The space complexity of above program is O(n^2)+O(n) O(n^2) for 2-d matrix and O(n)
for 1-d array
The space complexity of above program is O(n^2).
The reason for this is the a and b are of size n and hence both of them have a space complexity of O(2n) which is nothing but O(n).
Now the recursion is simply from n to 1 and each recursion call consumes O(n) space. Therefore space complexity will be O(n^2).

if else recursion worst time complexity

I have some trouble to figure out the worst time complexity of below code.
(This is not a homework, see https://leetcode.com/problems/integer-replacement/description/.)
int recursion (int n) {
if (n == 1)
return 0;
if (n % 2 == 0) {
return recursion(n/2) + 1
} else {
return min(recursion(n / 2 + 1) + 1, recursion(n - 1)) + 1;
}
}
The only thing I know is when N == 2 ^ k(k > 0), worst time complexity is O(logN).
However, I am unclear when N is not 2^k. Because even number / 2 can still get odd number. Some people said it is still O(LogN), but I am not convinced.
I know the code is not best solution, just wanna analyze the time complexity. I tried recursion tree and aggregate analysis, seems not help.
If n is even, we know that T(n) = T(n/2) + 1, and if n is odd we know that
T(n) = T(n/2 + 1) + T(n-1) + 1. In the latter case, as n is odd we know that n-1 must be even. if n/2 + 1 is even T(n) = T(n/4) + T(n/2) + 3 and if n/2 + 1 is odd T(n) = 2*T(n/4) + T(n/2) + 3.
From the above discussion, in the worst case T(n) is defined based on the T(n/2) and T(n/4) in a general case. From Akra-Bazzi Theorem we can say, T(n) = O(n^((log(1+sqrt(5))-log(2))/log(2))) ~ O(n^0.69) (from the first case) and T(n) = O(n) from the second case (which n/2 + 1 is odd).
However, for the more tight complexity, we should scrutinize more in our analysis.

What is the complexity of this piece of code

I had to determinate big O complexity of this piece of code.
I thought the answer is nlogn but apparently its n. Can anyone help explain why that is so?
void funct(int n)
{
for (int i = n; i > 0; i /= 2)
for(int j = 0; j < i; j++)
printf("%d\n", j%2);
}
That's geometric progression
The first time the inner loop is executed n times.
The second time it is executed n/2 times.
etc...
So we have the sequence:
n + n/2 + n/4 + ... + 1
so the final formula is:
n*(1 - (1/2)^(log n))/(1/2)
which is equivalent to n
Look these can be solved using Double Sigma's :
Let $ represents sigma.
so this problem is :
$(i=n downto 0 by a factor of 2 )$(j=0 to i-1) 1
where 1 represent a unit cost
now for inner sigma its sum of 1 i times that is = i
now problem is
$(i=n downto 1 by a factor of 2 ) i
which is sum of i values i.e. n+n/2+n/4+...+1(when n/2^x=1 or after log(n) terms)+0
or
n*(1+1/2+.....log(n) terms)
which is a convergent Geometric progression. and the result will be n*(1 - (1/2)^(log n))/(1/2) i.e O(n)
The outer loop, as I'm sure you can see is executed log(n) times. The inner loop is executed on average log(n)/2 times. So the printf statement is executed log(n) * (log(n) / 2) times which equals n / 2. So the complexity of the code is O(n).

Space complexity of a given recursive program

Consider the following C-function:
double foo (int n) {
int i;
double sum;
if (n == 0) return 1.0;
else {
sum = 0.0;
for (i = 0; i < n; i++)
sum + = foo (i);
return sum;
}
}
The space complexity of the above function is
1) O(1)
2) O(n)
3) O(n!)
4) O(n^n)
in the above question, according to me, answer should be (2) but answer is given as (3) option. Although it is recursive function but stack will never have more than O(n) stack depth. Can anyone explain me why is this answer (3) and where am I thinking wrong?
If You needed time complexity then it is certainly not O(N!) as many suggest but way less then that it is O(2^N).
Proof:-
T(N) = T(N-1) + T(N-2) + T(N-3) + T(N-4)........T(1)
moreover by above formula
T(N-1) = T(N-2) + T(N-3)...... T(1)
hence T(N) = T(N-1) + T(N-1) = 2*T(N-1)
solving above gives T(N) = O(2^N)
Whereas if you needed space complexity then for recursive function space complexity is calculated by the amount of stack space at max occupied by it at a moment and that in this case cannot exceed of O(N)
But in any case the answer is not O(N!) because that many computations are not done at all so how can stack occupy that much space.
Note:- Try to run the function for n = 20 if it doesnt cause memory overflow then answer given in text will be 20! which is larger than any memory but i think it will run in O(2^20) time without any stack overflow.
Space complexity is O(N). at any given time the space used is limited to:
N*sizeof_function_call_which_is_a_constant.
Think of it like this:
To calculate foo(n) . The program have to calculate: foo(0)+foo(1)+foo(2) ... foo(n-1):
Similarly for foo(n-1). The program have to recursively calculate: foo(0) + foo(1) + ... foo(n-2).
Basically you will have O(foo(n)) = n! + (n-1)! + (n-2)! + ... 1! = O(n!).
Hope this is clear.

Resources