There is a robot on an m x n
grid. The robot is initially located at the top-left corner (i.e., grid[0][0]
). The robot tries to move to the bottom-right corner (i.e., grid[m - 1][n - 1]
). The robot can only move either down or right at any point in time.
Given the two integers m
and n
, return the number of possible unique paths that the robot can take to reach the bottom-right corner.
The test cases are generated so that the answer will be less than or equal to 2 * 109
.
Example 1:
Input: m = 3, n = 7 Output: 28
Example 2:
Input: m = 3, n = 2 Output: 3 Explanation: From the top-left corner, there are a total of 3 ways to reach the bottom-right corner: 1. Right -> Down -> Down 2. Down -> Down -> Right 3. Down -> Right -> Down
Constraints:
1 <= m, n <= 100
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:
Imagine you're navigating a grid from the top left to the bottom right. The brute force approach involves trying every single possible path to get there. We explore each direction available at every step, one at a time, until we reach the end or get stuck.
Here's how the algorithm would work step-by-step:
def unique_paths_brute_force(number_of_rows, number_of_columns):
unique_path_count = 0
def traverse_grid(current_row, current_column):
nonlocal unique_path_count
# Base case: Reached the destination
if current_row == number_of_rows - 1 and current_column == number_of_columns - 1:
unique_path_count += 1
return
# Explore moving down
if current_row < number_of_rows - 1:
# Prevents exceeding the grid's boundaries.
traverse_grid(current_row + 1, current_column)
# Explore moving right
if current_column < number_of_columns - 1:
# Prevents exceeding the grid's boundaries.
traverse_grid(current_row, current_column + 1)
# Start traversal from the top-left corner.
traverse_grid(0, 0)
return unique_path_count
The best way to solve this is to realize that the number of ways to reach a spot is the sum of the ways to reach the spots above and to the left of it. We can build a grid that stores the number of ways to reach each location from the start.
Here's how the algorithm would work step-by-step:
def unique_paths(number_of_rows, number_of_columns):
path_grid = [[0] * number_of_columns for _ in range(number_of_rows)]
# Initialize the starting position with one path.
path_grid[0][0] = 1
for row_index in range(number_of_rows):
for column_index in range(number_of_columns):
if row_index == 0 and column_index == 0:
continue
paths_from_above = 0
if row_index > 0:
# Add paths from the cell above.
paths_from_above = path_grid[row_index - 1][column_index]
paths_from_left = 0
if column_index > 0:
# Add paths from the cell to the left.
paths_from_left = path_grid[row_index][column_index - 1]
# Accumulate paths from above and left.
path_grid[row_index][column_index] = paths_from_above + paths_from_left
# The bottom-right cell contains total unique paths.
return path_grid[number_of_rows - 1][number_of_columns - 1]
Case | How to Handle |
---|---|
m or n is zero | Return 0, as no path exists if either dimension is zero. |
m or n is negative | Return 0, as negative dimensions are invalid and indicate no path. |
m and n are both 1 | Return 1, as there is exactly one path: the robot is already at the destination. |
Large values of m and n leading to integer overflow | Use a data type that can accommodate larger numbers, such as long, or consider using dynamic programming to avoid recalculating the same path counts repeatedly which also helps reduce stack overflow. |
m is 1 and n is large | Return 1, as there's only one path: moving right n-1 times. |
n is 1 and m is large | Return 1, as there's only one path: moving down m-1 times. |
m and n are very large | Dynamic programming provides an efficient solution to avoid exponential time complexity and stack overflow issues of recursion. |
Check for integer overflow when calculating intermediate path sums using dynamic programming | Use a larger data type or implement overflow detection and appropriate error handling to avoid incorrect results. |