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.
Example:
Input: [ [1,3,1], [1,5,1], [4,2,1] ] Output: 7 Explanation: Because the path 1→3→1→1→1 minimizes the sum.
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.
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.
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.
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.
dp
with the same dimensions as the input grid.dp[0][0]
to grid[0][0]
.dp
by accumulating the values from the grid.(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]
.dp[m-1][n-1]
will be the minimum path sum.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
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.
Some potential edge cases include:
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
To test the solution comprehensively, consider a variety of test cases:
Using a testing framework like unittest
in Python can help automate and organize these tests.
When approaching dynamic programming problems:
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.
For further reading and practice: