Search code examples
algorithmtime-complexitypolynomials

Calculate time complexity of algorithm


So here is an algorithm that is supposed to return the polynomial value of P(x) of a given polynomial with any given x.

A[] is the coefficient array and P[] the power of x array.

(e.g. x^2 +2*x + 1 would have: A[] = {1,2,1} , P[]= {2,1,0})

Also, recPower() = O(logn)

int polynomial(int x, int A[], int P[], int l, int r)
{
    if (r - l == 1)
        return ( A[l] * recPower(x, P[l]) ) + ( A[r] * recPower (x, P[r]) );
    int m = (l + r) / 2;
    return polynomial(x, A, P, l, m) + polynomial(x, A, P, m, r);
}

How do I go about calculating this time complexity? I am perplexed due to the if statement. I have no idea what the recurrence relation will be.


Solution

  • Following observation might help: As soon as we have r = l + 1, we spend O(logn) time and we are done.

    My answer requires good understanding of Recursion Tree. So proceed wisely.

    So our aim is to find : after how many iterations will we be able to tell that we have r = l + 1?

    Lets find out:

    Focusing on return polynomial(x, A, P, l, m) + polynomial(x, A, P, m, r);

    Let us first consider left function polynomial(x, A, P, l, m). Key thing to note is that l , remains constant , in all subsequent left function called recursively.

    By left function I mean polynomial(x, A, P, l, m) and by right function I mean

    polynomial(x, A, P, m, r).

    For left function polynomial(x, A, P, l, m), We have:

    First iteration

    l = l and r = (l + r)/2
    

    Second iteration

    l = l and r = (l + (l + r)/2)/2
    

    which means that

    r = (2l + l + r)/2
    

    Third iteration

    l = l and r = (l + (l + (l + r)/2)/2)/2
    

    which means that

    r = (4l + 2l + l + r)/4
    

    Fourth iteration

    l = l and r = (l + (l + (l + (l + r)/2)/2)/2)/2
    

    which means that

    r = (8l + 4l + 2l + l + r)/8
    

    This means in nth iteration we have:

    r = (l(1 + 2 + 4 + 8 +......2^n-1) + r)/2^n 
    

    and terminating condition is r = l + 1

    Solving (l(1 + 2 + 4 + 8 +......2^n-1) + r)/2^n = l + 1, we get

    2^n = r - l
    

    This means that n = log(r - l). One might say that in all subsequent calls of left function we ignored the other call, that is right function call. The reason is this:

    Since in the right function call we l = m, where m is already a reduced , as we take the mean, and r = r, which is even more averaged this asymptotically wont have any effect on time complexity.

    So our recursion tree will have maximum depth = log(r - l). Its true that not all levels will be fully populated, but for the sake of simplicity, we assume this in asymptotic analysis. So after reaching a depth of log(r - l), we call function recPower, which takes O(logn) time. Total nodes (assuming all levels above are full) at depth log(r - l) is 2^(log(r - l) - 1). For a single node , we take O(logn) time.

    Therefore we have total time = O( logn*(2^(log(r - l) - 1)) ).