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
This problem asks to find the number of unique paths a robot can take to reach the bottom-right corner of an m x n
grid, starting from the top-left corner. The robot can only move down or right at any point.
This approach uses dynamic programming to solve the problem efficiently. We create a 2D array f
where f[i][j]
represents the number of unique paths to reach cell (i, j).
State Transition Equation:
The number of paths to reach (i, j) is the sum of paths from the cell above (i-1, j) and the cell to the left (i, j-1):
f[i][j] = f[i-1][j] + f[i][j-1]
Base Cases:
f[0][0] = 1
(There's one path to reach the starting cell).f[i][0] = 1
for all i (Only one way to reach any cell in the first column - moving down).f[0][j] = 1
for all j (Only one way to reach any cell in the first row - moving right).Algorithm:
f
of size m x n
with all elements set to 0.f[0][0] = 1
.f[i][j]
using the state transition equation.f[m-1][n-1]
.Optimization:
We can optimize space complexity by using a 1D array instead of a 2D array. Since f[i][j]
only depends on f[i-1][j]
and f[i][j-1]
, we can update the array in place.
Time Complexity: O(mn) - We iterate through the entire grid once. Space Complexity: O(n) for the optimized 1D array approach; O(mn) for the 2D array approach.
Approach 2 still uses a 2D array but initializes it differently, streamlining the code slightly. Approach 3 optimizes space even further by reducing it to a single 1D array. The core DP logic remains the same, but the array manipulation is more concise.
Here's the code in several programming languages demonstrating the optimized 1D array approach (Approach 3):
Python:
class Solution:
def uniquePaths(self, m: int, n: int) -> int:
f = [1] * n
for i in range(1, m):
for j in range(1, n):
f[j] += f[j - 1]
return f[-1]
Java:
class Solution {
public int uniquePaths(int m, int n) {
int[] f = new int[n];
Arrays.fill(f, 1);
for (int i = 1; i < m; ++i) {
for (int j = 1; j < n; ++j) {
f[j] += f[j - 1];
}
}
return f[n - 1];
}
}
C++:
class Solution {
public:
int uniquePaths(int m, int n) {
vector<int> f(n, 1);
for (int i = 1; i < m; ++i) {
for (int j = 1; j < n; ++j) {
f[j] += f[j - 1];
}
}
return f[n - 1];
}
};
JavaScript:
var uniquePaths = function(m, n) {
let f = new Array(n).fill(1);
for (let i = 1; i < m; i++) {
for (let j = 1; j < n; j++) {
f[j] += f[j - 1];
}
}
return f[n - 1];
};
The other languages (Go, TypeScript, Rust) would follow a very similar structure to this optimized 1D array approach. The core concept of dynamic programming remains consistent across all implementations.