You are given a m x n
grid filled with non-negative numbers. Your task is to find a path from the top-left cell (0, 0) to the bottom-right cell (m-1, n-1) such that the sum of all numbers along the path is minimized.
Constraints:
m == grid.length
n == grid[i].length
1 <= m, n <= 200
0 <= grid[i][j] <= 200
Example 1:
Input: grid = [[1,3,1],[1,5,1],[4,2,1]]
Output: 7
Explanation: The path 1 -> 3 -> 1 -> 1 -> 1 minimizes the sum.
Example 2:
Input: grid = [[1,2,3],[4,5,6]]
Output: 12
Explain how you would approach solving this problem and provide the code implementation for your solution. Discuss the time and space complexity of your approach. Also, consider and explain any edge cases.
When you get asked this question in a real-life environment, it will often be ambiguous (especially at FAANG). Make sure to ask these questions in that case:
The brute force way to find the minimum path sum involves exploring every possible route from the top-left corner to the bottom-right corner of the grid. We will calculate the sum of the numbers along each route and then compare them all. Finally, we'll pick the route with the smallest sum.
Here's how the algorithm would work step-by-step:
def minimum_path_sum_brute_force(grid):
if not grid:
return 0
number_of_rows = len(grid)
number_of_columns = len(grid[0])
def calculate_path_sum(row_index, column_index, current_path_sum):
# If we reach the bottom-right, return the path sum
if row_index == number_of_rows - 1 and column_index == number_of_columns - 1:
return current_path_sum + grid[row_index][column_index]
# If we go out of bounds, return infinity so it doesn't affect the min calculation
if row_index >= number_of_rows or column_index >= number_of_columns:
return float('inf')
current_path_sum += grid[row_index][column_index]
# Explore moving down
down_path_sum = calculate_path_sum(row_index + 1, column_index, current_path_sum)
# Explore moving right
right_path_sum = calculate_path_sum(row_index, column_index + 1, current_path_sum)
# Because the path must be minimum, pick the minimum path
return min(down_path_sum, right_path_sum)
return calculate_path_sum(0, 0, 0)
The goal is to find the path with the smallest total cost from the top-left to the bottom-right of a grid. The efficient approach builds the solution step-by-step, remembering the best cost to reach each cell and using that information to make smart decisions.
Here's how the algorithm would work step-by-step:
def minimum_path_sum(grid):
number_of_rows = len(grid)
number_of_columns = len(grid[0])
#Initialize first cell's path sum
grid[0][0] = grid[0][0]
# Initialize first column
for row_index in range(1, number_of_rows):
grid[row_index][0] += grid[row_index-1][0]
# Initialize first row
for column_index in range(1, number_of_columns):
grid[0][column_index] += grid[0][column_index-1]
# Iterate over grid to calc min path sum
for row_index in range(1, number_of_rows):
for column_index in range(1, number_of_columns):
# Choose the min path from top or left
grid[row_index][column_index] += min(grid[row_index-1][column_index], \
grid[row_index][column_index-1])
# Result stores min path sum from top-left to bottom-right
return grid[number_of_rows-1][number_of_columns-1]
Case | How to Handle |
---|---|
Null or empty grid | Return 0 if the grid is null or empty, indicating no path exists or the cost is zero. |
Grid with only one cell (1x1 grid) | Return the value of the single cell, as that is the only possible path. |
Grid with one row or one column | Iterate through the single row or column and sum the values to get the minimum path sum. |
Large grid dimensions (m and n are very large) | Dynamic programming avoids redundant calculations, providing an efficient solution. |
Grid with large integer values that could lead to integer overflow | Use a data type that can accommodate larger numbers, such as long or double, to prevent overflow. |
Grid with all cells having a value of 0 | The algorithm will correctly find the path with the sum of 0, indicating a path with no cost. |
Grid containing extremely large numbers, approaching the maximum integer value | Handle potential overflow by using appropriate data types like long, or consider using modular arithmetic if applicable based on the requirements. |
Invalid input: grid contains negative numbers (problem states non-negative) | Either throw an exception or handle the negative numbers, by for example taking the absolute value (after clarifying this with the interviewer). |