Unique Paths II
Solve this ProblemTest Case 1:
Test Case 2:
Test Case 3:
Constraints
- ◆
1 ≤ grid.length, grid[0].length ≤ 50 - ◆
grid[i][j] is 0 (open) or 1 (blocked)
Try the Dry Run
Don't just read the solution — watch it execute, one step at a time.
Approach & Solutions
Brute Force — Recursive Without Memoization
BruteThis is the same right/down search as plain Unique Paths, with one extra rule: stepping onto a blocked cell ends that path immediately and contributes nothing, exactly like stepping off the grid entirely. From any open cell, the number of ways to reach the bottom-right corner is the ways from moving down plus the ways from moving right — checked before either move is taken, since a blocked neighbor simply isn't a valid move to explore. Reaching the bottom-right corner while it's open counts as one complete path.
O(2^(m+n))O(m + n)1class Solution {
2 private int[][] grid;
3 private int m;
4 private int n;
5
6 public int uniquePathsII(int[][] grid) {
7 this.grid = grid;
8 this.m = grid.length;
9 this.n = grid[0].length;
10 return solve(0, 0);
11 }
12
13 private int solve(int i, int j) {
14 if (i >= m || j >= n || grid[i][j] == 1) return 0;
15 if (i == m - 1 && j == n - 1) return 1;
16 return solve(i + 1, j) + solve(i, j + 1);
17 }
18}Optimal — Bottom-Up 1D DP
OptimalSweep the same row-by-row count used for plain Unique Paths, with one change: whenever the current cell is blocked, its count is forced to 0 regardless of what arrived from above or the left, since no path can pass through it. An open cell still adds whatever count is already sitting there (arriving from above) to the count just computed at the cell to its left (arriving from the left) — except in the very first column, where there's no left-neighbor to add. The starting cell is seeded with a single way to reach it, provided it isn't itself blocked, and the entry at the last column after every row has been swept holds the total.
O(m × n)O(n)1class Solution {
2 public int uniquePathsII(int[][] grid) {
3 int m = grid.length, n = grid[0].length;
4 if (grid[0][0] == 1) return 0;
5 int[] dp = new int[n];
6 dp[0] = 1;
7 for (int i = 0; i < m; i++) {
8 for (int j = 0; j < n; j++) {
9 if (grid[i][j] == 1) {
10 dp[j] = 0;
11 } else if (j > 0) {
12 dp[j] += dp[j - 1];
13 }
14 }
15 }
16 return dp[n - 1];
17 }
18}