Search code examples
c++dynamic-programmingmemoization

Memoized solution gives TLE while tabulated solution does not


I am attempting the following question from Interviewbit:

Given a m x n grid filled with non-negative numbers, find a path from top left to bottom right which minimizes the sum of all numbers along its path.

NOTE: You can only move either down or right at any point in time.

I have written the following memoized solution:

int minPath(vector<vector<int> > &A, int i, int j, vector<vector<int> > &dp) {
if (dp[i][j] >= 0)
    return dp[i][j];
else if (i == A.size() - 1 && j == A[0].size() - 1)
    return dp[i][j] = A[i][j];
else if (i == A.size() - 1)
    return dp[i][j] = A[i][j] + minPath(A, i, j + 1, dp);
else if (j == A[0].size() - 1)
    return dp[i][j] = A[i][j] + minPath(A, i + 1, j, dp);
else
    return dp[i][j] = A[i][j] + min(minPath(A, i + 1, j, dp), minPath(A, i, j + 1, dp));
}

int Solution::minPathSum(vector<vector<int> > &A) {
if (A.size() == 0)
    return 0;

vector<vector<int> > dp(A.size(), vector<int>(A[0].size(), -1));
return minPath(A, 0, 0, dp);
}

This solution is giving a TLE during submission.

After a while I took a look at the editorial code, and they have followed the tabulation approach as follows:

int minPathSum(vector<vector<int> > &grid) {
        if (grid.size() == 0) return 0;
        int m = grid.size(), n = grid[0].size();
        int minPath[m + 1][n + 1];
        for (int i = 0; i < m; i++) {
            minPath[i][0] = grid[i][0]; 
            if (i > 0) minPath[i][0] += minPath[i - 1][0];
            for (int j = 1; j < n; j++) {
                minPath[i][j] = grid[i][j] + minPath[i][j-1];
                if (i > 0) minPath[i][j] = min(minPath[i][j], grid[i][j] + minPath[i-1][j]);
            }
        }
    return minPath[m-1][n-1];
}

According to me, the time complexity of both the codes seem same, yet mine seems to be giving TLE. Where exactly am I going wrong?


Solution

  • The test cases have negative numbers in the grid ( though they have explicitly mentioned non-negative numbers). So dp[i][j] can be negative but your function will never consider those values. Just used another vector to store the visited cell and it got accepted.

    int minPath(vector<vector<int> > &A, int i, int j, vector<vector<int> > &dp,vector<vector<bool> > &vis)
    {
        if (vis[i][j])
            return dp[i][j];
        vis[i][j] = 1;
        if (i == A.size() - 1 && j == A[0].size() - 1)
            return dp[i][j] = A[i][j];
        else if (i == A.size() - 1)
            return dp[i][j] = A[i][j] + minPath(A, i, j + 1, dp, vis);
        else if (j == A[0].size() - 1)
            return dp[i][j] = A[i][j] + minPath(A, i + 1, j, dp, vis);
        else
            return dp[i][j] = A[i][j] + min(minPath(A, i + 1, j, dp, vis), minPath(A, i, j + 1, dp, vis));
    }
    
    int Solution::minPathSum(vector<vector<int> > &A)
    {
        if (A.size() == 0)
            return 0;
    
        vector<vector<int> > dp(A.size(), vector<int>(A[0].size(), -1));
        vector<vector<bool> > vis(A.size(), vector<bool>(A[0].size(), 0));
        return minPath(A, 0, 0, dp, vis);
    }