Start learning free

LESSON 421 OF 673 · MEMOIZATION

Minimum Path Sum III in Python (Time Complexity: O(m*n))

Practice O(n2) - DP Read the full explanation

You get a grid of non-negative numbers with m rows and n columns.

Return the smallest sum of a path from the top-left cell to the bottom-right cell.

At each step, the path moves one cell right or one cell down. The sum includes every cell on the path, even the first and the last.

Example 1:

Input:
[
  [2,8,1],
  [3,4,6],
  [7,1,2]
]
Output: 12
Explanation: The path with the smallest sum is 2 → 3 → 4 → 1 → 2.
It goes down, right, down and right.
Its sum is 2 + 3 + 4 + 1 + 2 = 12.

Example 2:

Input:
[
  [5,0,9,1]
]
Output: 15
Explanation: There is only one row.
The only path goes right through every cell.
Its sum is 5 + 0 + 9 + 1 = 15.

Example 3:

Input:
[
  [1,4],
  [2,8],
  [6,0]
]
Output: 9
Explanation: The path with the smallest sum is 1 → 2 → 6 → 0.
It goes down the left column, then right.
Its sum is 1 + 2 + 6 + 0 = 9.

Constraints:

  • 1 to 100 rows.
  • 1 to 100 columns.
  • Each number is from 0 to 99.
STEP 1 OF 5
    Ctrl + Enter to check

    PYTHON · MEMOIZATION

    Minimum Path Sum in Python, explained

    Understanding the Problem

    The core challenge of this problem is to find the path from the top-left corner to the bottom-right corner of a grid that results in the minimum sum of the numbers along the path. The only allowed movements are to the right or downward. This problem is a classic example of dynamic programming, where we can break down the problem into smaller subproblems and build up the solution from there.

    Approach

    To solve this problem, we can use dynamic programming. The idea is to create a 2D array dp where dp[i][j] represents the minimum path sum to reach cell (i, j). We can fill this array by considering the minimum path sum to reach the current cell from either the cell above it or the cell to the left of it.

    Naive Solution

    A naive solution would involve exploring all possible paths from the top-left to the bottom-right corner, which would be highly inefficient due to the exponential number of possible paths.

    Optimized Solution

    The optimized solution involves using dynamic programming to build up the solution efficiently. We initialize the dp array with the same dimensions as the input grid. The value at dp[0][0] is simply the value of the top-left cell of the grid. For each cell, we update the dp value by considering the minimum path sum from the top or left cell.

    Algorithm

    1. Initialize a 2D array dp with the same dimensions as the input grid.
    2. Set dp[0][0] to grid[0][0].
    3. Fill the first row and first column of dp by accumulating the values from the grid.
    4. For each cell (i, j) in the grid, update dp[i][j] to be the minimum of dp[i-1][j] and dp[i][j-1] plus the value of grid[i][j].
    5. The value at dp[m-1][n-1] will be the minimum path sum.

    Code Implementation

    def minPathSum(grid):
        # Get the number of rows and columns
        m, n = len(grid), len(grid[0])
        
        # Initialize the dp array with the same dimensions as grid
        dp = [[0] * n for _ in range(m)]
        
        # Set the value of the top-left cell
        dp[0][0] = grid[0][0]
        
        # Fill the first row
        for j in range(1, n):
            dp[0][j] = dp[0][j-1] + grid[0][j]
        
        # Fill the first column
        for i in range(1, m):
            dp[i][0] = dp[i-1][0] + grid[i][0]
        
        # Fill the rest of the dp array
        for i in range(1, m):
            for j in range(1, n):
                dp[i][j] = min(dp[i-1][j], dp[i][j-1]) + grid[i][j]
        
        # The value at the bottom-right cell is the minimum path sum
        return dp[m-1][n-1]
    
    # Example usage
    grid = [
        [1, 3, 1],
        [1, 5, 1],
        [4, 2, 1]
    ]
    print(minPathSum(grid))  # Output: 7
    

    Complexity Analysis

    The time complexity of this solution is O(m * n) because we iterate through each cell of the grid once. The space complexity is also O(m * n) due to the additional dp array.

    Edge Cases

    Some potential edge cases include:

    • An empty grid: The function should handle this gracefully.
    • A grid with only one row or one column: The function should still compute the correct minimum path sum.

    For example:

    grid = [[1]]
    print(minPathSum(grid))  # Output: 1
    
    grid = [[1, 2, 3]]
    print(minPathSum(grid))  # Output: 6
    
    grid = [[1], [2], [3]]
    print(minPathSum(grid))  # Output: 6
    

    Testing

    To test the solution comprehensively, consider a variety of test cases:

    • Simple cases with small grids.
    • Grids with varying dimensions.
    • Grids with large values to test for potential overflow issues.

    Using a testing framework like unittest in Python can help automate and organize these tests.

    Thinking and Problem-Solving Tips

    When approaching dynamic programming problems:

    • Break down the problem into smaller subproblems.
    • Think about how to build up the solution from these subproblems.
    • Consider edge cases and how your solution handles them.
    • Practice similar problems to strengthen your understanding.

    Conclusion

    Understanding and solving dynamic programming problems like the minimum path sum is crucial for developing strong problem-solving skills. By breaking down the problem, considering edge cases, and testing thoroughly, you can develop efficient and robust solutions.

    Additional Resources

    For further reading and practice:

    Keep going with Python650+ step-by-step lessons, from your first line of code to coding interviews. Free to start.
    Start learning free