Problem
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 or diagonally 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.
Examples
Example 1:
Input:
m = 3, n = 3
Output:
13
Solution
This problem is very similar to Unique Paths in Grid 1 - Count all paths moving right or down, just adding the diagonal bit.
Method 1 - Recursion
The recursive approach exhaustively tries all possible moves from each position until it either reaches the bottom-right corner (m-1, n-1)
or goes out of bounds.
Code
Java
public class Solution {
public int uniquePaths(int m, int n) {
return dfs(0, 0, m, n);
}
private int dfs(int row, int col, int m, int n) {
if (row == m - 1 && col == n - 1) return 1; // Reached destination
if (row >= m || col >= n) return 0; // Out of bounds
// Right + Down + Diagonal
return dfs(row, col + 1, m, n) + dfs(row + 1, col, m, n) + dfs(row + 1, col + 1, m, n);
}
}
Complexity
- ⏰ Time complexity:
O(3^(m+n))
, because each call can lead to three other calls. - 🧺 Space complexity:
O(n)
, assuming recursion stack
Method 2 - Top Down DP with Memoization
Top-down DP with memoization enhances the recursive approach by caching the results of subproblems. This prevents re-computation for the same cells multiple times.
Code
Java
public class Solution {
public int uniquePaths(int m, int n) {
return findPaths(0, 0, m, n, new Integer[m][n]);
}
private int findPaths(int row, int col, int m, int n, Integer[][] memo) {
if (row == m - 1 && col == n - 1) {
return 1;
}
if (row >= m || col >= n) {
return 0;
}
if (memo[row][col] != null) {
return memo[row][col];
}
int right = findPaths(row, col + 1, m, n, memo);
int down = findPaths(row + 1, col, m, n, memo);
int diagonal = findPaths(row + 1, col + 1, m, n, memo);
memo[row][col] = right + down + diagonal;
return memo[row][col];
}
}
Complexity
- ⏰ Time complexity:
O(m*n)
- 🧺 Space complexity:
O(m*n)
Method 3 - Bottom up DP
Bottom-up DP constructs the solution iteratively using a table where dp[i][j]
represents the number of ways to reach cell (i, j)
. Each cell in the dp
table is filled based on the number of ways to reach the cell to its left, above it, and diagonally top-left.
Code
Java
public class Solution {
public int uniquePaths(int m, int n) {
int[][] dp = new int[m][n];
for (int i = 0; i < m; i++) {
dp[i][0] = 1; // Only 1 way to go straight down
}
for (int j = 0; j < n; j++) {
dp[0][j] = 1; // Only 1 way to go straight right
}
for (int i = 1; i < m; i++) {
for (int j = 1; j < n; j++) {
dp[i][j] = dp[i - 1][j] + dp[i][j - 1] + dp[i - 1][j - 1]; // Down + Right + Diagonal
}
}
return dp[m - 1][n - 1];
}
}
Complexity
- ⏰ Time complexity:
O(m*n)
- 🧺 Space complexity:
O(m*n)