Search code examples
javacalgorithmdynamic-programmingtopdown

Runtime complexity of recursion inside loop with memoization


I would like to know how to determine the time complexity for the following code, using top-down dynamic programming approach with memoization (note that i, k, d can be any integer value):

solve(i, k, d) {
    if (k >= d) {
        A[i][k] = 0;
        return 0;
    }

    if (i == 0) {
        A[i][k] = 0;
        return 0;
    }

    if (A[i][k] == null) {
        for (int j = 0; j < k + 1; j++) {
            A[i][k] = solve(i - 1, (k + 1 - j), d);
        }
    }

    return A[i][k];
}

Solution

  • Issue :

    solve(i - 1, (k + 1 - j), d)
    

    will give out of bound error when j = 0 as A index should go from 0 to K [K being largest index]


    ANSWER : The function will give O(n * n) complexity.


    Intuition :

    (it is clear that the worst case is the one where there are no solutions, so I focus on that)

    Since the recursive call is made before putting values in the memoization-cache, the last (shortest) suffixes will get cached first. This is because the function is first called with a array of length N, which then calls itself with a array of length N-1, which then .... , with a array of len 0, which is cached and returns, then the array of length 1 is cached and returns, ..., length N is cached and returns.

    Explanation :

    Assuming size of matrix I x K and Considering worst case,

    [Note] In worst case, Function call will start from right bottom of matrix

    A initialization happens in two cases :

    • k >= d
    • i == 0

    [Note] In worst case, k is always less that d.

    For loop for `(I, K)`
    - Recursion call `for (i-1, k:[K to 0])` 
    - Update value for `A[i, k]`
    

    [Note] i = 0 is base case when function initializes A and returns 0.